ios delegates - mobile conf rio 2014
DESCRIPTION
Presented at Mobile Conf Rio 2014, Brazil. The content is in Brazilian Portuguese. Discussion of the Delegate pattern and its implementation in iOS API. Samples from the SDK and a custom interaction using delegates. Shows techniques such as performSelector: calls, delegation through protocol and delegation using blocks. Code samples: https://github.com/osnipso/mobileconf2014 Caelum IP-67 course on iOS (in Brazilian Portuguese): http://www.caelum.com.br/curso-ios-iphone-ipad/TRANSCRIPT
![Page 1: iOS Delegates - Mobile Conf Rio 2014](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/1.jpg)
DELEGATESDesvendando esse poderoso padrão
na API do iOS
![Page 2: iOS Delegates - Mobile Conf Rio 2014](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/2.jpg)
APRESENTAÇÃO
Osni Oliveira
@osnipso
github.com/osnipso
![Page 3: iOS Delegates - Mobile Conf Rio 2014](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/3.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/4.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/5.jpg)
DELEGATES
Colaboração entre objetos
![Page 6: iOS Delegates - Mobile Conf Rio 2014](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/6.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/7.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/8.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/9.jpg)
CONCEITO
Delega(framework) Delegado
MensagemProtocolo (opcional)
![Page 10: iOS Delegates - Mobile Conf Rio 2014](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/10.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/11.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/12.jpg)
CONCEITO
•Opcional
• Contrato formal
• Acoplamento através do contrato (leve)
Protocolo
![Page 13: iOS Delegates - Mobile Conf Rio 2014](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/13.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/14.jpg)
CONCEITO
Delega(framework) Delegado
MensagemProtocolo (opcional)
![Page 15: iOS Delegates - Mobile Conf Rio 2014](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/15.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/16.jpg)
EXEMPLO: UIAlertView
UIAlertView ViewController
alertView:clickedButtonAtIndex:
UIAlertViewDelegate
delegatereferência
![Page 17: iOS Delegates - Mobile Conf Rio 2014](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/17.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/18.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/19.jpg)
EXEMPLO: UIImagePickerController
UIImagePickerController ViewController
imagePickerController:didFinishPickingMediaWithInfo:
UINavigationControllerDelegate (*)UIImagePickerControllerDelegate
delegatereferência
![Page 20: iOS Delegates - Mobile Conf Rio 2014](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/20.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/21.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/22.jpg)
OUTROS EXEMPLOS
• UIApplicationDelegate
(AppDelegate.h)
@interface AppDelegate : UIResponder <UIApplicationDelegate>
![Page 23: iOS Delegates - Mobile Conf Rio 2014](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/23.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/24.jpg)
EXEMPLO - SEM PROTOCOLO
• UIPickerController, porém seleciona ao confirmar
• Permite cancelar seleção
• Exibido como modal
![Page 25: iOS Delegates - Mobile Conf Rio 2014](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/25.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/26.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/27.jpg)
EXEMPLO - SEM PROTOCOLO
• Problemas com o compilador:
• Até dá pra desligar esse aviso, mas...
![Page 28: iOS Delegates - Mobile Conf Rio 2014](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/28.jpg)
EXEMPLO - SEM PROTOCOLO
MYPickerViewController ViewController
cancelPicking (opcional)pickedItem: (opcional)
NSObject
delegatereferência
![Page 29: iOS Delegates - Mobile Conf Rio 2014](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/29.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/30.jpg)
EXEMPLO - SEM PROTOCOLO
Limitações
• Protocolo NSObject
performSelector:
performSelector:withObject:
performSelector:withObject:withObject:
• Boxing (syntax sugar)
![Page 31: iOS Delegates - Mobile Conf Rio 2014](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/31.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/32.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/33.jpg)
EXEMPLO - COM PROTOCOLO
MYPickerViewController ViewController
cancelPickerViewController: (opcional)pickerViewController:pickedItem:
MYPickerViewControllerDelegate
delegatereferência
![Page 34: iOS Delegates - Mobile Conf Rio 2014](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/34.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/35.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/36.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/37.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/38.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/39.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/40.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/41.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/42.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/43.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/44.jpg)
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](https://reader034.vdocuments.site/reader034/viewer/2022042614/5571c623d8b42a3f5e8b45d3/html5/thumbnails/45.jpg)
OBRIGADO!
slideshare.net/osnipso/ios-delegates-mobile-conf-rio-2014
github.com/osnipso/mobileconf2014
@osnipso