iOS Delegates - Mobile Conf Rio 2014

725 visualizações

Publicada em

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/

Publicada em: Software
0 comentários
1 gostou
Estatísticas
Notas
  • Seja o primeiro a comentar

Sem downloads
Visualizações
Visualizações totais
725
No SlideShare
0
A partir de incorporações
0
Número de incorporações
4
Ações
Compartilhamentos
0
Downloads
10
Comentários
0
Gostaram
1
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

iOS Delegates - Mobile Conf Rio 2014

  1. 1. DELEGATES Desvendando esse poderoso padrão na API do iOS
  2. 2. APRESENTAÇÃO Osni Oliveira osni.oliveira@caelum.com.br @osnipso github.com/osnipso
  3. 3. CONHECIMENTO • Básico de Objective-C • Conceitos fundamentais do iOS • Views • Actions • Outlets slideshare.net/osnipso/primeiros-passos-no-ios-com-objectivec
  4. 4. 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)
  5. 5. DELEGATES Colaboração entre objetos
  6. 6. 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
  7. 7. 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
  8. 8. 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.
  9. 9. CONCEITO Delega (framework) Delegado Mensagem Protocolo (opcional)
  10. 10. CONCEITO • Recebe o delegado como dependência (injeção) • Faz a “primeira parte” da tarefa • Envia a mensagem Delega (framework)
  11. 11. CONCEITO • É injetado para o objeto que delega • Garante a implementação da mensagem • Faz a “segunda parte” da tarefa Delegado
  12. 12. CONCEITO • Opcional • Contrato formal • Acoplamento através do contrato (leve) Protocolo
  13. 13. 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!
  14. 14. CONCEITO Delega (framework) Delegado Mensagem Protocolo (opcional)
  15. 15. 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 { ... }
  16. 16. EXEMPLO: UIAlertView UIAlertView ViewController alertView:clickedButtonAtIndex: UIAlertViewDelegate delegate referência
  17. 17. 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
  18. 18. 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 { ... }
  19. 19. EXEMPLO: UIImagePickerController UIImagePickerController ViewController imagePickerController:didFinishPickingMediaWithInfo: UINavigationControllerDelegate (*) UIImagePickerControllerDelegate delegate referência
  20. 20. 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
  21. 21. OUTROS EXEMPLOS • UITableView • UITableViewDelegate (interação com UI / exibição avançada) • UITableViewDataSource (exibição básica)
  22. 22. OUTROS EXEMPLOS • UIApplicationDelegate (AppDelegate.h) @interface AppDelegate : UIResponder <UIApplicationDelegate>
  23. 23. 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.
  24. 24. EXEMPLO - SEM PROTOCOLO • UIPickerController, porém seleciona ao confirmar • Permite cancelar seleção • Exibido como modal
  25. 25. 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)
  26. 26. 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)]; }
  27. 27. EXEMPLO - SEM PROTOCOLO • Problemas com o compilador: • Até dá pra desligar esse aviso, mas...
  28. 28. EXEMPLO - SEM PROTOCOLO MYPickerViewController ViewController cancelPicking (opcional) pickedItem: (opcional) NSObject delegate referência
  29. 29. 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!
  30. 30. EXEMPLO - SEM PROTOCOLO Limitações • Protocolo NSObject performSelector: performSelector:withObject: performSelector:withObject:withObject: • Boxing (syntax sugar)
  31. 31. 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;
  32. 32. 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]; }
  33. 33. EXEMPLO - COM PROTOCOLO MYPickerViewController ViewController cancelPickerViewController: (opcional) pickerViewController:pickedItem: MYPickerViewControllerDelegate delegate referência
  34. 34. 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!
  35. 35. EXEMPLO - COM BLOCOS (MYPickerViewController.h) @property (copy, atomic) void (^cancelBlock) (MYPickerViewController *pickerViewController); @property (copy, atomic) void (^successBlock) (MYPickerViewController *pickerViewController, NSInteger itemIndex);
  36. 36. 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); } }
  37. 37. 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];
  38. 38. EXEMPLO - COM BLOCOS MYPickerViewController ViewController void (^cancelBlock)(MYPickerViewController *pickerViewController); void (^successBlock)(MYPickerViewController *pickerViewController, NSInteger itemIndex); Contrato está na assinatura do bloco! bloco bloco (cópia)
  39. 39. 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...
  40. 40. 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;
  41. 41. EXEMPLO - COM BLOCOS • Cuidado com ciclos de retenção! MYPickerViewController ViewController bloco bloco (cópia de self - “strong”) picker pickerViewController (strong)
  42. 42. 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 “^”)
  43. 43. 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]; };
  44. 44. 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
  45. 45. OBRIGADO! slideshare.net/osnipso/ios-delegates-mobile-conf-rio-2014 github.com/osnipso/mobileconf2014 osni.oliveira@caelum.com.br @osnipso

×