Transcript
Page 1: iOS Delegates - Mobile Conf Rio 2014

DELEGATESDesvendando esse poderoso padrão

na API do iOS

Page 2: iOS Delegates - Mobile Conf Rio 2014

APRESENTAÇÃO

Osni Oliveira

[email protected]

@osnipso

github.com/osnipso

Page 3: iOS Delegates - Mobile Conf Rio 2014

CONHECIMENTO

• Básico de Objective-C

• Conceitos fundamentais do iOS

• Views

• Actions

•Outlets

slideshare.net/osnipso/primeiros-passos-no-ios-com-objectivec

Page 4: iOS Delegates - Mobile Conf Rio 2014

DELEGATES

• Padrão de Projeto (Design Pattern)

•Divisão de responsabilidades

• Princípio da responsabilidade única

• Comunicação entre objetos

• Inversão de Controle (IoC)

Page 5: iOS Delegates - Mobile Conf Rio 2014

DELEGATES

Colaboração entre objetos

Page 6: iOS Delegates - Mobile Conf Rio 2014

IMPORTÂNCIA

• É *o* padrão mais importante no iOS

•Muito utilizado pela API

•Muito utilizado pelos desenvolvedores

• Imprescindível compreender

•Necessário dominar

• Boa prática utilizar - padronização

Page 7: iOS Delegates - Mobile Conf Rio 2014

DEFINIÇÕES

•Delegation (iOS Developer Library - Cocoa Core Competencies)

https://developer.apple.com/library/ios/documentation/general/conceptual/DevPedia-CocoaCore/Delegation.html

•Delegates and Data Sources (iOS Developer Library - Concepts in Objective-C Programming)

https://developer.apple.com/library/ios/documentation/general/conceptual/CocoaEncyclopedia/DelegatesandDataSources/DelegatesandDataSources.html#//apple_ref/doc/uid/TP40010810-CH11

Page 8: iOS Delegates - Mobile Conf Rio 2014

CONCEITO

Apple (Cocoa Core Competencies):

Delegação é um padrão simples e poderoso em que um objeto em um programa age no lugar de, ou em coordenação com outro objeto.

(...)

O objeto que delega é tipicamente um objeto do framework e o delegado é tipicamente um objeto controller customizado.

Page 9: iOS Delegates - Mobile Conf Rio 2014

CONCEITO

Delega(framework) Delegado

MensagemProtocolo (opcional)

Page 10: iOS Delegates - Mobile Conf Rio 2014

CONCEITO

• Recebe o delegado como dependência (injeção)

• Faz a “primeira parte” da tarefa

• Envia a mensagem

Delega(framework)

Page 11: iOS Delegates - Mobile Conf Rio 2014

CONCEITO

• É injetado para o objeto que delega

• Garante a implementação da mensagem

• Faz a “segunda parte” da tarefa

Delegado

Page 12: iOS Delegates - Mobile Conf Rio 2014

CONCEITO

•Opcional

• Contrato formal

• Acoplamento através do contrato (leve)

Protocolo

Page 13: iOS Delegates - Mobile Conf Rio 2014

CONCEITO

Dois objetos colaboram para realizar uma tarefa.

O primeiro, faz até onde ele consegue fazer.

O que ele não consegue? Delega para o segundo!

Page 14: iOS Delegates - Mobile Conf Rio 2014

CONCEITO

Delega(framework) Delegado

MensagemProtocolo (opcional)

Page 15: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO: UIAlertView

(ViewController.h)

@interface ViewController : UIViewController <UIAlertViewDelegate>

(ViewController.m)

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Exemplo 1" message:@"Começando com delegates" delegate:self cancelButtonTitle:@"Cancela" otherButtonTitles:@"Ok", nil];

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { ... }

Page 16: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO: UIAlertView

UIAlertView ViewController

alertView:clickedButtonAtIndex:

UIAlertViewDelegate

delegatereferência

Page 17: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO: UIAlertView

• Sabe exibir a mensagem e os botões

• Sabe qual botão foi tocado (“clicado”) pelo usuário

•Não sabe o que fazer a partir desse ponto!

•Depende da aplicação

• Aciona o delegado para fazer

Page 18: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO: UIImagePickerController

(ViewController.h)

@interface ViewController : UIViewController <UINavigationControllerDelegate, UIImagePickerControllerDelegate>

(ViewController.m)

UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;imagePicker.delegate = self; [self presentViewController:imagePicker animated:YES completion:nil];

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { ... }

Page 19: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO: UIImagePickerController

UIImagePickerController ViewController

imagePickerController:didFinishPickingMediaWithInfo:

UINavigationControllerDelegate (*)UIImagePickerControllerDelegate

delegatereferência

Page 20: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO: UIImagePickerController

• Sabe exibir a galeria de imagens/vídeos (câmera, etc.)

• Sabe qual image/vídeo foi selecionado pelo usuário

•Não sabe o que fazer a partir desse ponto!

•Depende da aplicação

• Aciona o delegado para fazer

Page 21: iOS Delegates - Mobile Conf Rio 2014

OUTROS EXEMPLOS

• UITableView

• UITableViewDelegate (interação com UI / exibição avançada)

• UITableViewDataSource (exibição básica)

Page 22: iOS Delegates - Mobile Conf Rio 2014

OUTROS EXEMPLOS

• UIApplicationDelegate

(AppDelegate.h)

@interface AppDelegate : UIResponder <UIApplicationDelegate>

Page 23: iOS Delegates - Mobile Conf Rio 2014

E O CONTRATO?

• Acoplamento a um protocolo específico

•Melhor que acoplar diretamente à classe...

•Obrigatoriedade de implementar todas as mensagens (?)

• Péssimo. Implementações vazias, adapters, etc.

Page 24: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO - SEM PROTOCOLO

• UIPickerController, porém seleciona ao confirmar

• Permite cancelar seleção

• Exibido como modal

Page 25: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO - SEM PROTOCOLO

• MYPickerViewController é quem implementa UIPickerViewDataSource, UIPickerViewDelegate

(MYPickerViewController.h)

@interface MYPickerViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate>

• Exibe conteúdo fixo

• Seguindo a mesma idéia, podemos perguntar a um DataSource o que exibir... (desafio)

Page 26: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO - SEM PROTOCOLO

• Precisamos usar performSelector:

•Delegate pode ser genérico, mas precisa implementar o protocolo NSObject

(MYPickerViewController.h)

@property (weak, atomic) id<NSObject> delegate;

(MYPickerViewController.m)

if ([self.delegate respondsToSelector:@selector(pickedItem:)]) { [self.delegate performSelector:@selector(pickedItem:) withObject:@(self.selectedItem)];}

Page 27: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO - SEM PROTOCOLO

• Problemas com o compilador:

• Até dá pra desligar esse aviso, mas...

Page 28: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO - SEM PROTOCOLO

MYPickerViewController ViewController

cancelPicking (opcional)pickedItem: (opcional)

NSObject

delegatereferência

Page 29: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO - SEM PROTOCOLO

Prós:

•Menos trabalho

• Sem implementações desnecessárias, adapters

Contras:

• Contrato implícito!

• Sem autocomplete

• Sem ajuda do compilador

•Muito limitado!

Page 30: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO - SEM PROTOCOLO

Limitações

• Protocolo NSObject

performSelector:

performSelector:withObject:

performSelector:withObject:withObject:

• Boxing (syntax sugar)

Page 31: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO - COM PROTOCOLO

(MYPickerViewController.h)

@class MYPickerViewController;

@protocol MYPickerViewControllerDelegate <NSObject>

@optional- (void)cancelPickerViewController: (MYPickerViewController *)pickerViewController;

@required- (void)pickerViewController:(MYPickerViewController *)pickerViewController pickedItem:(NSInteger)itemIndex;

@end

@property (weak, atomic) id<MYPickerViewControllerDelegate> delegate;

Page 32: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO - COM PROTOCOLO

(MYPickerViewController.m)

- (IBAction)cancelPicking:(id)sender{ if ([self.delegate respondsToSelector: @selector(cancelPickerViewController:)]) { [self.delegate cancelPickerViewController:self]; }}

- (IBAction)confirmPicking:(id)sender{ [self.delegate pickerViewController:self pickedItem:self.selectedItem];}

Page 33: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO - COM PROTOCOLO

MYPickerViewController ViewController

cancelPickerViewController: (opcional)pickerViewController:pickedItem:

MYPickerViewControllerDelegate

delegatereferência

Page 34: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO - COM PROTOCOLO

Prós:

• Contrato explícito

• Com autocomplete

• Com ajuda do compilador

•Mais flexível e poderoso

Contras:

•Mais trabalho

Com @optional:

• Sem implementações desnecessárias, adapters

• Continua autocomplete!

Page 35: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO - COM BLOCOS

(MYPickerViewController.h)

@property (copy, atomic) void (^cancelBlock) (MYPickerViewController *pickerViewController);

@property (copy, atomic) void (^successBlock) (MYPickerViewController *pickerViewController, NSInteger itemIndex);

Page 36: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO - COM BLOCOS

(MYPickerViewController.m)

- (IBAction)cancelPicking:(id)sender{ if (self.cancelBlock) { self.cancelBlock(self); }}

- (IBAction)confirmPicking:(id)sender{ if (self.successBlock) { self.successBlock(self, self.selectedItem); }}

Page 37: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO - COM BLOCOS

(ViewController.m)

MYPickerViewController *pickerViewController = [[MYPickerViewController alloc] init]; pickerViewController.cancelBlock = ^(MYPickerViewController *pickerViewController) { [self dismissViewControllerAnimated:YES completion:nil]; }; pickerViewController.successBlock = ^(MYPickerViewController *pickerViewController, NSInteger itemIndex) { NSLog(@"Item selecionado: %ld", (unsigned long)itemIndex);

[self dismissViewControllerAnimated:YES completion:nil]; };

[self presentViewController:pickerViewController animated:YES completion:nil];

Page 38: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO - COM BLOCOS

MYPickerViewController ViewController

void (^cancelBlock)(MYPickerViewController *pickerViewController);void (^successBlock)(MYPickerViewController *pickerViewController, NSInteger itemIndex);

Contrato está na assinatura do bloco!

blocobloco (cópia)

Page 39: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO - COM BLOCOS

Prós:

• Contrato explícito

• Com ajuda do compilador

• (Ainda) mais flexível e poderoso

Contras:

• Uma propriedade por callback

• Sintaxe bizarra!

• Problemas de gerenciamento de memória...

Page 40: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO - COM BLOCOS

•Dá pra melhorar um pouquinho a sintaxe...

(MYPickerViewController.h)

typedef void (^MYPickerViewControllerCancelBlock) (MYPickerViewController *pickerViewController);

typedef void (^MYPickerViewControllerSuccessBlock) (MYPickerViewController *pickerViewController, NSInteger itemIndex);

@property (copy, atomic) MYPickerViewControllerCancelBlock cancelBlock;@property (copy, atomic) MYPickerViewControllerSuccessBlock successBlock;

Page 41: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO - COM BLOCOS

• Cuidado com ciclos de retenção!

MYPickerViewController ViewController

blocobloco (cópia de self - “strong”)

picker

pickerViewController (strong)

Page 42: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO - COM BLOCOS

Cuidado:

• Fechamento (closure) no escopo da instância

• Programação funcional - paradigma misto

• Extensão da linguagem C, ainda não padronizada

Curiosidade:

• Sintaxe é a mesma de ponteiro de função (“*” vira “^”)

Page 43: iOS Delegates - Mobile Conf Rio 2014

EXEMPLO - COM BLOCOS

• Resolvendo (possíveis) ciclos de retenção:

(ViewController.m)

typeof(self) __weak weakSelf = self;

pickerViewController.cancelBlock = ^(MYPickerViewController *pickerViewController) { [weakSelf dismissViewControllerAnimated:YES completion:nil]; }; pickerViewController.successBlock = ^(MYPickerViewController *pickerViewController, NSInteger itemIndex) { NSLog(@"Item selecionado: %ld", (unsigned long)itemIndex);

[weakSelf dismissViewControllerAnimated:YES completion:nil]; };

Page 44: iOS Delegates - Mobile Conf Rio 2014

DICAS

• Procure entender o conceito (callback...?)

•Observe as APIs e como elas utilizam o padrão

•Na dúvida, implemente com protocolos (tradicional)

• APIs novas usam cada vez mais blocos - tendência

Page 45: iOS Delegates - Mobile Conf Rio 2014

OBRIGADO!

slideshare.net/osnipso/ios-delegates-mobile-conf-rio-2014

github.com/osnipso/mobileconf2014

[email protected]

@osnipso


Recommended