La mise en réseau facilitée avec AFNetworking

Le réseautage est difficile. Divers éléments mobiles sont impliqués et de nombreux facteurs doivent être pris en compte pour que cela fonctionne. Heureusement, un certain nombre de bibliothèques à code source libre ont été créées au fil du temps pour faciliter la mise en réseau. AFNetworking, créé et géré par les habitants de Gowalla, est l'une de ces bibliothèques. Ce tutoriel vous présentera le framework AFNetworking tout en montrant comment interroger l'API iTunes Store.!

Dans ce tutoriel, je vais vous présenter AFNetworking et vous montrer un aperçu de ce que cette bibliothèque a à offrir. Après avoir passé quelques minutes avec cette bibliothèque, vous remarquerez qu’elle a été conçue pour être facile à utiliser. Cela accélérera non seulement votre développement, mais prendra également en charge de nombreuses tâches de réseau fastidieuses. Nous allons créer une application simple qui interroge iTunes Store sur les films correspondant au terme de recherche "harry". Les résultats de notre requête seront affichés dans une table..


Résumé du projet

L'application que nous sommes sur le point de créer interroge l'API iTunes Store Search. En particulier, nous recherchons dans l'iTunes Store des films qui correspondent au terme de recherche "harry". Si notre requête aboutit, nous traitons les résultats et les affichons dans une vue sous forme de tableau. Chaque ligne représente un film avec un titre, un réalisateur et une vignette montrant l’illustration du film. Prêt? Commençons.


Configuration du projet

Avant de nous salir les mains avec AFNetworking, nous devons construire une base de base. Cela signifie configurer notre projet, créer une vue sous forme de tableau et ajouter une vue d'indicateur d'activité. Nous afficherons l'indicateur d'activité lors du traitement de notre demande par l'iTunes Store. Cela donnera à l'utilisateur un précieux retour d'information souvent négligé.

Créez un nouveau projet dans Xcode en sélectionnant le Application à vue unique modèle de la liste des modèles. Nommez votre application NetworkingIsFun, entrez un identifiant d'entreprise, définissez "iPhone" pour la famille d'appareils et décochez "Utiliser les scénarimages". Vous pouvez laisser le reste intact, mais assurez-vous que Utiliser le comptage automatique des références est vérifié. Indiquez à Xcode où vous souhaitez enregistrer votre projet et cliquez sur "Enregistrer".


Ajout des vues de table et d'indicateur d'activité

Même si Interface Builder est génial, je construis souvent mes interfaces par programmation, et c'est ce que nous allons faire dans ce tutoriel. Cela nous permettra de nous concentrer sur le code sans être distrait par Interface Builder. Ouvrir ViewController.h et créer trois variables d'instance (ivars) ainsi que des propriétés pour ces ivars. Puisque nous allons travailler avec une vue de table, n'oubliez pas de rendre votre contrôleur de vue conforme à la UITableViewDataSource et UITableViewDelegate protocoles. Le fichier d'en-tête de votre contrôleur de vue devrait maintenant ressembler à celui ci-dessous:

 #importation  @interface ViewController: UIViewController  UITableView * _tableView; UIActivityIndicatorView * _activityIndicatorView; NSArray * _movies;  @property (nonatomic, keep) UITableView * tableView; @property (nonatomic, keep) UIActivityIndicatorView * activityIndicatorView; @property (nonatomic, keep) films NSArray *; @fin

Si vous êtes déconcerté par l'utilisation de traits de soulignement, je vous recommande de lire à ce sujet ici. N'hésitez pas à omettre les traits de soulignement si vous pensez que le résultat est moche ou vous met mal à l'aise. En dehors des soulignés, il ne devrait y avoir aucune surprise. Nous déclarons nos UITableView et UIActivityIndicatorView ainsi qu’un NSArray, que nous utiliserons pour stocker les résultats que nous avons obtenus de notre requête de recherche. Prêt? Passons au fichier d'implémentation de notre contrôleur de vue.

Depuis que nous avons déclaré trois propriétés dans notre fichier d’en-tête, nous devons synthétiser leurs accesseurs dans ViewController.m. Encore une fois, si les traits de soulignement vous déroutent, vous pouvez les laisser de côté..

 @synthesize tableView = _tableView, activityIndicatorView = _activityIndicatorView, movies = _movies;

Dans notre viewDidLoad méthode, nous configurons nos vues de table et d’indicateurs d’activité. Le code ci-dessous devrait être explicite pour la plupart. Si vous n'avez jamais configuré de vue de tableau sans utiliser Interface Builder, il est possible que quelques lignes vous soient inconnues. Au lieu de câbler la vue de table dans Interface Builder, nous nous en occupons dans la viewDidLoad méthode. Après avoir appelé la superclasse ' viewDidLoad méthode, nous initialisons notre vue table avec un cadre et un style, et nous définissons notre contrôleur de vue comme source de données et délégué de notre vue table. Lorsque notre application est lancée, nous masquons notre vue tableau car nous n'avons rien à afficher tant que notre requête n'a renvoyé aucun résultat. Avant d'ajouter la vue tabulaire en tant que sous-vue à la vue de notre contrôleur de vue, nous avons défini son masque de redimensionnement automatique. Le masque de redimensionnement automatique définit le mode de redimensionnement de la vue tableau si la vue parent, la vue du contrôleur de la vue à laquelle nous ajoutons la vue tableau, change de taille. Cela se produit lorsque l'appareil est pivoté, par exemple. Confus? Ne t'inquiète pas pour ça. Ce n'est pas important pour cette application.

 - (void) viewDidLoad [super viewDidLoad]; // Configuration de la vue Table self.tableView = [[UITableView alloc] initWithFrame: CGRectMake (0.0, 0.0, self.view.bounds.size.width, self.view.bounds.size.height) style: UITableViewStylePlain]; self.tableView.dataSource = self; self.tableView.delegate = self; self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; self.tableView.hidden = YES; [self.view addSubview: self.tableView]; // Configuration de la vue d'indicateur d'activité self.activityIndicatorView = [[UIActivityIndicatorView alloc]] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleGray]; self.activityIndicatorView.hidesWhenStopped = YES; self.activityIndicatorView.center = self.view.center; [self.view addSubview: self.activityIndicatorView]; [self.activityIndicatorView startAnimating]; // Initialisation de la source de données self.movies = [[NSArray alloc] init]; 

La configuration de la vue d'indicateur d'activité est tout aussi simple. Nous initialisons la vue des indicateurs d’activité avec un style prédéfini, définissons sa se cache à l'arrêt propriété à OUI, et placez-le au centre de sa vue parente. Après l'ajout à la vue du contrôleur de vue, nous commençons à animer l'indicateur d'activité. L’indicateur d’activité s’affiche automatiquement puisque nous avons défini son se cache à l'arrêt propriété à OUI.

À la fin de notre viewDidLoad méthode, on initialise le films tableau. Nous l'utiliserons plus tard pour stocker les résultats de notre requête de recherche..


Protocoles d'affichage de table

Pour ce tutoriel, nous n'implémenterons que deux méthodes du protocole de source de données de vue table. Ces deux méthodes sont nécessaires. C'est l'implémentation minimale requise pour que notre vue Table soit opérationnelle. Même si nous avons défini notre contrôleur de vue en tant que délégué de la vue de table, nous n'utilisons aucune des méthodes de délégation dans notre application. Si vous avez déjà utilisé une vue sous forme de tableau, vous ne trouverez pas de surprises dans les implémentations de méthodes présentées ci-dessous..

 - (NSInteger) tableView: (UITableView *) tableView numberOfRowsInSection: (NSInteger) section if (self.movies && self.movies.count) return self.movies.count;  else retour 0;  - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath statique NSString * cellID = @ "Identificateur de cellule"; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: cellID]; if (! cell) cell = [[UITableViewCell alloc]] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: cellID];  cellule de retour; 

Dans tableView: numberOfRowsInSection:, nous devons renvoyer le nombre de lignes dans chaque section de la vue tableau. Dans notre exemple, la vue tableau ne contient qu'une section (valeur par défaut), ce qui simplifie un peu la tâche. Nous vérifions d’abord si notre films variable n'est pas nil et nous vérifions qu'il contient des éléments. Si ces deux conditions sont remplies, nous renvoyons le nombre d'éléments dans le groupe de films, sinon, nous renvoyons zéro..

Notre tableView: cellForRowAtIndexPath: La méthode est basique aussi. Nous commençons par demander à notre vue de table s’il existe une cellule que nous pouvons réutiliser. Si ce n'est pas le cas, nous créons une nouvelle cellule avec un identifiant de style et de réutilisation. Nous terminons notre mise en œuvre en retournant notre cellule. Cela fera pour le moment. Vous pouvez maintenant construire et exécuter votre application. Si vous avez suivi les étapes correctement, vous devriez voir l'indicateur d'activité tourner comme un fou et la vue tabulaire devrait être masquée.


Ajouter AFNetworking au mélange

Ajouter AFNetworking à votre projet est simple comme bonjour. Commencez par télécharger la bibliothèque à partir de GitHub et extrayez l'archive. L’archive contient un dossier nommé AFNetworking, qui contient les fichiers source que nous devons inclure dans notre projet. Faites glisser tout ce dossier dans votre projet Xcode et assurez-vous de vérifier Copier des éléments dans le dossier du groupe de destination (si nécessaire) et ajoutez les fichiers sources à votre cible aussi bien.

Après avoir ajouté la bibliothèque AFNetworking à votre projet, construisez et exécutez votre application, puis observez les événements se dégrader. Qu'est-il arrivé à notre projet? Pourquoi avons-nous tous ces avertissements et erreurs? Lorsque nous avons configuré notre projet Xcode, nous avons activé Comptage automatique des références (ARC). Au moment de la rédaction, la bibliothèque AFNetworking n’utilise pas ARC. Ne vous inquiétez pas, cependant, nous pouvons toujours utiliser cette bibliothèque soignée avec très peu d'effort. Tout ce que nous avons à faire, c'est d'informer le compilateur que tous les fichiers source de la bibliothèque AFNetworking n'utilisent pas ARC. C'est tout.

Comment faisons-nous cela? Sélectionnez votre projet dans le Navigateur de projet et sélectionnez votre cible. Clique le Phases de construction onglet dans la navigation du haut et ouvrez le Compiler les sources tiroir. Ce tableau vous montre tous les fichiers source que le compilateur compilera au moment de la compilation. La colonne de gauche montre les noms des fichiers et la colonne de droite montre les drapeaux que le compilateur devrait connaître.

Vous pouvez voir ces indicateurs sous forme d'instructions ou de messages pour le compilateur. Tout ce que vous avez à faire est d’ajouter un indicateur de compilation à chaque fichier source de la bibliothèque AFNetworking. Pour ce faire, sélectionnez un fichier source dans la liste et double-cliquez sur la cellule dans la colonne de droite. Une petite fenêtre apparaît dans laquelle vous pouvez ajouter un ou plusieurs drapeaux du compilateur. Dans notre cas, tapez simplement -fno-objc-arc et cliquez Terminé. Cet indicateur indique au compilateur que le fichier source n'utilise pas ARC. Assurez-vous que vous ajoutez cet indicateur aux dix fichiers source de la bibliothèque AFNetworking..


Interrogation de l'API iTunes Store Search

AFNetworking est une bibliothèque qui peut faire beaucoup pour vous, mais aujourd'hui, nous n'utiliserons que deux fonctionnalités intéressantes. Avant de pouvoir utiliser les classes AFNetworking, nous devons ajouter l'instruction d'importation suivante juste en dessous de la première instruction d'importation dans le fichier d'implémentation de votre contrôleur de vue..

 #import "AFNetworking.h"

Cette déclaration d'importation nous donnera accès à toutes les classes AFNetworking. Retournez à notre contrôleur de vue viewDidLoad méthode et ajoutez l’extrait suivant immédiatement après l’initialisation de la films tableau.

 NSURL * url = [[NSURL alloc] initWithString: @ "http://itunes.apple.com/search?term=harry&country=us&entity=movie"]; NSURLRequest * request = [[NSURLRequest alloc] initWithURL: url]; AFJSONRequestOperation * operation = [AFJSONRequestOperation JSONRequestOperationWithRequest: succès de la demande: ^ (demande NSURLRequest *, réponse NSHTTPURLResponse *, id JSON) NSLog (@ "% @", JSON);  échec: ^ (demande NSURLRequest *, réponse NSHTTPURLResponse *, erreur NSError *, id JSON) NSLog (@ "La requête a échoué avec l'erreur:% @,% @", erreur, error.userInfo); ]; [début de l'opération];

Laissez-moi vous expliquer ce qui se passe. Dans la première ligne, nous créons le NSURL pour notre demande. La chaîne que nous utilisons lors de l'initialisation est conforme au format attendu par l'API iTunes Store Search. La syntaxe de l'API de recherche est assez simple: le terme que nous recherchons est "harry", nous limitons notre recherche au site américain iTunes Store et nous ne recherchons que des films. Facile, droit?

Ensuite, nous initialisons un NSURLRequest et transmettons le NSURL que nous venons de créer. Puis AFNetworking entre en jeu. AFNetworking contient quelques classes très spécialisées qui rendent notre travail très facile. Celui que nous utilisons ici est AFJSONRequestOperation. Il s'agit d'une classe conçue pour extraire et analyser des données JSON en arrière-plan. Comme son nom l'indique, cette classe est une sous-classe de NSOperation ou, pour être plus précis, une des superclasses de cette classe hérite de NSOperation. La classe vous permet d'extraire les données demandées et analyse également la réponse JSON. Cela signifie que nous n'avons pas à traiter avec du JSON brut. Les données renvoyées sont prêtes à être utilisées dans votre application. AFNetworking utilise l'analyseur JSON intégré sur iOS 5 et utilise son propre analyseur JSON pour les anciennes versions iOS..

Utiliser AFJSONRequestOperation est facile car il n’a qu’une méthode de classe. Cette méthode de classe accepte trois arguments: (1) un NSURLRequest, (2) un bloc de succès, exécuté lorsque la requête aboutit, et (3) un bloc d'échec, exécuté lorsque la requête échoue. Si les blocs vous sont nouveaux ou si vous n'êtes pas à l'aise avec leur utilisation, je vous recommande de lire le tutoriel de Collin Ruffenach sur les blocs et l'énumération sur Mobiletuts +. Le bloc de succès prend trois arguments: (1) notre requête NSURL, (2) la requête NSHTTPURLResponse de notre demande et (3) un objet JSON analysé. Le bloc d'échec est presque identique. La seule différence est qu’il faut un argument supplémentaire, une erreur NSError contenant davantage d’informations sur ce qui ne va pas au cas où notre demande échoue..

À des fins de test, nous enregistrons l'objet JSON analysé pour voir ce que l'API de recherche iTunes Store nous renvoie. De plus, nous enregistrons également l'erreur dans le bloc d'échec au cas où notre demande échouerait. Avant de construire et d’exécuter à nouveau notre application, nous devons démarrer l’opération en appelant début sur notre objet opération. Construisez et exécutez votre application et examinez le résultat dans la console..

Si tout se passe bien, vous verrez les résultats de notre requête consignés sur la console. L'objet JSON analysé est un dictionnaire avec deux clés: (1) resultCount, qui contient le nombre de résultats renvoyés et (2) la valeur réelle résultats comme un tableau de dictionnaires. Nous avons non seulement consigné la réponse à la console pour voir si notre requête a abouti, mais nous pouvons maintenant voir les clés pour chaque élément du tableau de résultats. Nous aurons besoin de ces clés pour afficher certaines informations dans notre vue tableau.


Remplir la vue tableau

Nous sommes maintenant prêts à afficher les résultats dans notre vue tableau. Remplacez l'instruction de journal dans le bloc de succès par l'extrait de code présenté ci-dessous. Nous commençons par affecter le tableau de résultats de l'objet de réponse au tableau de films. Il ne reste plus qu'à masquer l'indicateur d'activité en l'arrêtant, en affichant la vue tableau et en rechargeant la vue tableau avec les nouvelles données stockées dans le tableau de films..

 self.movies = [JSON objectForKey: @ "résultats"]; [self.activityIndicatorView stopAnimating]; [self.tableView setHidden: NO]; [self.tableView reloadData];

Ensuite, nous modifions le tableView: cellForRowAtIndexPath: méthode. Ajustez votre implémentation pour refléter celle ci-dessous. Après avoir obtenu une référence à une cellule, nous interrogeons le tableau de films pour trouver le bon élément et mettons à jour les étiquettes de la cellule avec le titre et le directeur du film. Construire et exécuter votre application.

 - (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath statique NSString * cellID = @ "Identificateur de cellule"; UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: cellID]; if (! cell) cell = [[UITableViewCell alloc]] initWithStyle: UITableViewCellStyleSubtitle reuseIdentifier: cellID];  NSDictionary * movie = [self.movies objectAtIndex: indexPath.row]; cell.textLabel.text = [movie objectForKey: @ "trackName"]; cell.detailTextLabel.text = [movie objectForKey: @ "artistName"]; cellule de retour; 

Vous avez peut-être remarqué qu'il n'y a pas de vignettes visibles. Réglons cela en ajoutant trois lignes supplémentaires à notre tableView: cellForRowAtIndexPath: méthode. Construire et exécuter votre application.

 NSURL * url = [[NSURL alloc] initWithString: [movie objectForKey: @ "artworkUrl100"]]; NSData * data = [NSData dataWithContentsOfURL: url]; cell.imageView.image = [[UIImage alloc] initWithData: data];

Avez-vous remarqué que notre affichage sous forme de tableau ne défile pas correctement? Pourquoi donc? Comme je l'ai mentionné dans un précédent tutoriel, vous devez toujours vous assurer que le fil conducteur de votre application reste réactif. Dans la mise en œuvre actuelle de notre tableView: cellForRowAtIndexPath: méthode, nous téléchargeons les vignettes sur le fil principal. Cela signifie que l'interface utilisateur ne peut pas être mise à jour tant qu'une demande de vignette n'est pas terminée. Nos vignettes étant minuscules, les demandes ne prennent pas beaucoup de temps, mais imaginez que vous adoptiez la même approche pour les actifs plus importants. L'expérience utilisateur serait terrible. Même pour notre application simple, l'expérience utilisateur est inacceptable. Cependant, nous pouvons y remédier avec une fonctionnalité très utile de la bibliothèque AFNetworking.


AFNetworking à la rescousse

Les créateurs d'AFNetworking ont également reconnu la nécessité de télécharger des ressources en arrière-plan. Ils ont donc créé une catégorie pour UIImageView. Cette catégorie vous permet de télécharger des images en arrière-plan avec seulement deux lignes de code. Cette catégorie est un véritable épargnant de vie. Regardez l'extrait ci-dessous.

 NSURL * url = [[NSURL alloc] initWithString: [movie objectForKey: @ "artworkUrl100"]]; [cell.imageView setImageWithURL: url placeholderImage: [UIImage imageNamed: @ "placeholder"]];

La première ligne de code reste la même. Sur la deuxième ligne, nous indiquons à la vue de l’image où se trouve la vignette en passant un NSURL et nous passons à une image de substitution, qui est affichée tant que notre demande n’a pas renvoyé de réponse. À quel point cela est cool? Il suffit d’ajouter une image de substitution à notre projet. Cela peut être n'importe quelle image, mais vous pouvez trouver l'image que j'ai utilisée comme espace réservé dans le fichier de téléchargement joint à ce didacticiel. Une fois que vous avez ajouté l'image de marque de réservation, générez et exécutez votre application et testez par vous-même comment la vue en tableau défile!


Conclusion

Notez que notre application est très basique dans son exécution car elle ne fait aucune mise en cache et nous ne pouvons que rechercher dans l'iTunes Store le terme "harry" dans la section films. Cependant, avec très peu d'effort, vous pouvez créer une application élégante pour effectuer une recherche plus dynamique dans l'iTunes Store..

J'espère que ce tutoriel vous a convaincu que la bibliothèque AFNetworking est un excellent outil à avoir dans votre arsenal. Il peut faire beaucoup plus que ce que je vous ai montré dans ce billet, mais l'objectif principal de ce tutoriel est de vous familiariser avec AFNetworking et de le rendre opérationnel dans un scénario réel..