[iOS] delegate in Objective C vs Swift

lundi 30 janvier 2017

Dans cet article, je vais vous présenter comment mettre en place la technique de delegation de méthodes entre deux classes. Cette technique permet d’implémenter une méthode dans une classe qui est appelé à un moment donnée dans une autre classe. On peut voir cela comme la technique de hook dans le web. On créé dans un view controller un appel vers une méthode qui n’est pas implémentée dans cette classe mais qu’on offre la possibilité dans une autre classe d’implémenter comme un hook qu’on utilise quand on en a besoin.

Cette technique est très utilisé en Objective C et Swift, pour tous ces composants. Par exemple: Quand on souhaite remplir une tableview, on utilise le « UITableViewDelegate » avec la méthode déléguée « cellForRowAt » qui permet de définir la cellule.

Cette technique est très utile quand on souhaite mettre à jour des composants UI d’un viewControlleur quand on se retrouve dans un autre avant d’accéder au viewControler.

Nous allons voir comment implémenter cette technique en Objective C et Swift:

La première étape consiste à créer un protocol delegate dans le controlleur qui détermine quand la méthode sera appelée!

Objective C

@protocol DetailViewControllerProtocol <NSObject>
@optional
- (void)didFinishTask;
@end
@interface ....

Swift

protocol DetailViewControllerDelegate: class {
  func didFinishTask
}

Toujours dans cette classe, on créé une propriété de la classe comme étant notre objet delegate de type du protocole.

Objective C

@property (weak, nonatomic) id <DetailViewControllerDelegate> delegate;

Swift

weak var delegate:DetailViewControllerDelegate?

Ensuite nous utilisons cette propriété dans une méthode de notre classe au moment où on souhaite delégué notre méthode. Par exemple dans une DetailViewController lorsqu’on fait un back de la navigation controlleur pour par exemple rafraichir la vue parente.

Objective C

[self.delegate didFinishTask];

Swift

delegate?.didFinishTask()

Voilà maintenant notre classe Delegate est opérationnel et terminée. Maintenant, il faut implémenter dans la classe parente le classe delegate et implémenter le code de la méthode déléguée. Il faut rajouter l’héritage du protocole dans l’interface du viewController et implémenter la méthode.

Objective C

@interface MasterViewController () <DetailViewControllerDelegateProtocol>
@end
- (void)didFinishTask {
  // do stuff like updating the UI
}

En Swift il y a deux méthodes soit dans la classe soit on créé une extension.

class MasterViewController: DetailViewControllerDelegate {
  func didFinishTask {
    // do stuff like updating the UI
  }
}

OU

extension MasterViewController: DetailViewControllerDelegate {
  func didFinishTask {
    // do stuff like updating the UI
  }
}

Maintenant, il faut surtout pas oublier de setter le delegate au viewcontrolleur!

// Objective-C
detailViewController.delegate = self;
// Swift
detailViewController.delegate = self

Dans mon cas c’est dans le prepare du segue de la liste vers le DetailViewController qu’on assigne le viewControlleur (self) à la propriété delegate de DetailViewController. Il faut bien sur passer le viewController qui implémente la méthode déléguée à la classe qui va faire appel à cette méthode.

Tags: Delegate , IOS , Objective C , Swift