Introduction
Développer une application pour iPhone vous fait rêver, mais vous ne vous êtes pas encore décidé à mettre la main à la pâte ? Alors cet article est fait pour vous !
Vous allez découvrir ici tous les aspects du développement d’une application iOS au cours d’une série d’articles successifs que nous vous livrerons tous les mois. Nous avons choisi pour vous guider de créer une application présentant des données de films, récupérées depuis le site RottenTomatoes.
Dans ce premier article, vous allez apprendre à créer votre projet, commencer l’interface graphique et récupérer la liste des films actuellement au cinéma. À vos marques, prêts ? Codez !
Création du projet sous XCode
Afin de développer notre première application iPhone, nous avons besoin d’un ordinateur Mac et la dernière version de Xcode, l’environnement de développement d’Apple, qui permet la construction d’applications à la fois pour iOS et pour Mac OS.
Xcode – dont la dernière version stable, au moment de l’écriture, est la 4.6.3 – est librement téléchargeable depuis le Mac App Store. Il est livré avec des outils de développement nécessaires à l’instrumentation de nos applications et iOS Simulator, un environnement qui permet l’exécution d’application iOS (soit iPhone ou iPad) sur notre ordinateur.
Pour installer et tester nos applications maison sur notre iPhone ou iPad nous avons besoin d’un compte développeur qui – au moment de la rédaction – coûte 79 € par an et permet de connecter jusqu’à 100 périphériques de test. L’exécution d’une application sur l’iOS Simulator, cependant, ne nécessite pas de compte payant et fournit une expérience cohérente avec celle d’un vrai terminal avec peu ou pas de différence par rapport à un périphérique réel, surtout lorsque nous utilisons les APIs les plus courantes.
Une fois que nous avons installé Xcode sur notre ordinateur, nous allons enfin pouvoir le lancer. Dans la fenêtre de dialogue de démarrage, nous serons en mesure de créer notre premier projet Xcode en sélectionnant «Create a new Xcode project".
L’écran suivant va nous permettre de choisir un modèle de projet. Chaque modèle offre des classes de commodité et du code standard. Afin d’apprendre les éléments fondateurs d’une application iOS, dans ce tutoriel, nous allons opter pour le modèle "Empty application" qui ne fournit aucune classe autre que AppDelegate, le point d’entrée de notre application.
Après avoir sélectionné "Empty application", nous allons cliquer sur le bouton "Next", qui nous amènera à un écran où nous pourrons saisir les informations de base de notre application :
- "Product Name" : le nom de l’application,
- "Organization Name" : le nom de notre société,
- "Company Identifier" : une chaîne de caractères qui doit identifier nos applications et doit être unique pour chaque entreprise ou développeur qui soumet une application sur l’App Store,
- "Class Prefix" (optionnel) : les lettres qui précéderont les noms de toutes les classes que nous allons créer,
- "Devices" : les types de dispositifs que nous aimerions cibler
et trois cases à cocher.
En ce qui concerne «Product Name» et «Organization Name» nous pouvons évidemment choisir n’importe quelle valeur. «Company Identifier» devra être une chaîne de caractères similaire à une url inversée, de type "fr.nom_societe". Dans la liste déroulante "Devices", nous pouvons choisir entre «iPhone», «iPad» ou «Universal». Ce dernier choix consiste en une application ciblant les deux types de terminaux. Nous n’avons pas besoin ici de sélectionner "Use Core Data», car Core Data est un gestionnaire de base de données qui permet de stocker et d’interroger des valeurs au sein de notre application. Dans notre cas, les données se trouvent sur le serveur de RottenTomatoes, donc nous n’avons pas besoin de les garder dans l’application. Nous sélectionnons "Use Automatic Reference Counting», un mécanisme qui simplifie grandement la gestion de la mémoire dans notre code, et "Include Unit Tests". Lorsque nous aurons terminé avec les options, en cliquant sur "Next" nous pourrons choisir le dossier qui stockera nos fichiers de projet. C’est la dernière étape de la configuration du projet : nous pouvons maintenant commencer à développer notre Movie App. Finalement !
Création du splash screen et de l’icône
Le splash screen
Quand le système lance une application sur n’importe quel type d’appareil (iPhone, iPad, iPod), une image statique est temporairement affichée à l’écran. C’est l’application qui est lancée qui se doit d’embarquer cette image statique. Le but de cette image est de pouvoir afficher quelque chose à l’écran immédiatement après que l’utilisateur ait décidé de lancer l’application. Cela permet aussi à l’application de disposer d’un petit temps afin qu’elle puisse s’initialiser et préparer les différentes vues et données à afficher. Une fois que l’application a terminé la phase d’initlialisation, le système retire automatiquement le splash screen et affiche les vues de l’application.
Chaque application iOS doit fournir au moins une image pour le splash screen. L’application que nous souhaitons mettre en place est conçue pour l’iPhone et de ce fait, nous avons besoin de trois images pour le splash screen : Default.png, pour les iPhone non retina (par exemple, l’iPhone 3GS) et Default@2x.png pour les iPhone retina hormis l’iPhone 5 (par exemple, l’iPhone 4S) et Default-568h@2x.png pour l’iPhone 5. Les image du splash screen doivent obligatoirement être des fichiers PNG.
Voici les formats à repecter :
Default.png : 320x480px
Default@2x.png : 640x960px
Default-568h@2x.png : 640x1136px
Lors de la création de notre projet iOS, des images noires ont été générées par défaut et sont présentes dans l’arborescence du projet.
Afin de personnaliser notre application, il suffit de créer trois images respectants les dimensions listées ci-dessus et de remplacer les images générées. Une fois cette opération faite, nous pouvons vérifier la bonne prise en compte de ces nouvelles images par Xcode en allant dans les paramètres de notre application :
Avant la configuration des images splash screen
Après la configuration des images splash screen
L’icône
Chaque application iOS a besoin d’une icône qui sera affichée sur l’écran d’accueil de l’appareil mais aussi sur l’App Store. En réalité, une application peut spécifier une multitude d’icônes qui seront utilisées dans différentes situations. Par exemple une application peut fournir une petite icône qui sera affichée et utilisée dans les résultats de spotlight et elle peut fournir une icône beaucoup plus grosse et en haute résolution qui sera utilisée pour les appareils supportant l’affichage retina.
Pour une application exclusivement pour l’iPhone, il faut embarquer à minima deux formats d’icônes :
Icon.png : 57x57px
Icon@2x.png : 114x114px (pour les écrans retina)
Afin d’indiquer à Xcode les icônes que l’on souhaite utiliser pour notre application, il suffit de se rendre dans l’écran des paramètres de notre application (voir la capture d’écran précédente) et de faire du glisser/déposer au niveau de la zone "App Icons" : l’image Icon.png doit être déposée dans le carré de gauche, et l’image Icon@2x.png, correspondant à l’icône pour les écrans retina, doit aller dans le carré de droite :
En effectuant cette opération, Xcode copie automatiquement les images dans le répertoire du projet et les ajoute dans l’arborescence du projet. À cette étape, lorsque vous lancez l’application iPhone (sur simulateur par exemple), vous verrez le splash screen au démarrage ainsi qu’une jolie icône sur l’écran d’accueil de l’iPhone.
Mise en place du storyboard
Les storyboards ont été présentés avec l’arrivée d’iOS 5 et permettent d’économiser beaucoup de temps lors de la conception d’applications. Un storyboard représente les écrans de l’application ainsi que les transitions entre ces derniers. Notre application ne contient que quelques écrans mais une application bien plus complexe peut très bien avoir plusieurs storyboards. Voici un exemple de storyboard :
Sans même connaître le périmètre fonctionnel de cette application, on peut d’ores et déjà savoir que l’application disposent de deux écrans et qu’il est possible de naviguer entre ces deux écrans.
Afin de créer le storyboard de notre application, rendez-vous dans Xcode puis dans le menu File → New → File, sélectionnez "User Interface" dans la colonne de gauche puis "Storyboard". Appuyez sur "Next" et laissez les paramètres par défaut.
Une fois cette étape effectuée, le nouveau storyboard apparait dans l’arborescence du projet. Après l’avoir sélectionné, nous pouvons voir qu’il est pour l’instant totalement vide, ce qui est normal. L’objectif ici est de le remplir pour indiquer à l’application quel écran afficher au démarrage.
L’éditeur de storyboard est très pratique : il est possible d’y glisser/déposer de nouveaux éléments à partir d’une bibliothèque d’objets (qui se trouve en bas de la colonne "Utilities" à droite). Mettons en œuvre cette opération en faisant glisser au milieu du storyboard un View Controller depuis la bibliothèque d’éléments :
Vous remarquerez qu’une flèche pointe vers ce viewController. Cela indique que cet élément est le viewController initial, c’est-à-dire que c’est le viewController à afficher au démarrage de l’application. Afin de manipuler un peu plus le storybard, je vous invite à glisser dans le viewController fraichement créé un label (UILabel) et de changer son texte, écrivons par exemple "Ecran d’accueil" :
Une application, pour être affichée à l’écran, dispose d’une window. Cette window se doit d’avoir un viewController par défaut à afficher au démarrage. Si l’on se rend dans le .m de l’AppDelegate de notre l’application, on y verra la méthode – (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions. Cette méthode est automatiquement appelée par le système lors du démarrage de l’application. C’est ici que la window de l’application est instanciée et que l’on doit y associer le viewController par défaut à afficher.
Pour cela, il suffit de créer une référence à notre storyboard, et grâce à cette référence il sera ensuite possible de demander au storyboard une référence sur le viewController initial. Une fois celui-ci obtenu, il ne reste plus qu’à l’associer à la window. Voici à quoi ressemble la méthode avec ces informations :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Reference the App storyboard UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Storyboard" bundle:nil]; UIViewController *rootVC = [storyboard instantiateInitialViewController]; self.window.rootViewController = rootVC; [self.window makeKeyAndVisible]; return YES; }
A cette étape, si vous compilez l’application et la lancez, vous verrez l’écran d’accueil, tel qu’il est spécifié sur le storyboard :
Mise en place d’un UITableViewController
Dans le cadre de cette article, nous souhaitons mettre en place une application qui affiche une liste de films. Et qui dit liste sous iOS dit UITableView. Une UITableView est un composant qui est en définitif un "tableau" présentant une série de données sous la forme d’une liste. Cette liste peut être personnalisée à souhait. Ici, nous allons nous contenter de personnaliser la UITableView (la liste) avec des cellules (des lignes) qui contiennent la photo, le titre et l’année des films.
Afin de mettre en place notre UITableView, nous allons utiliser un UITableViewController. Cet objet est un controller très pratique car il encapsule directement une UITableView. Commençons par créer une classe qui hérite de UITableViewController. Pour cela allez dans le menu File → New → File puis choisissez Cocoa Touch dans la liste de gauche et enfin Objective-C class. Dans l’étape suivante renseignez ‘UITableViewController’ comme sous-classe et ‘MATableViewController’ comme nom de classe puis validez.
A cette étape, notre classe héritant de UITableViewController est créée mais il reste encore à l’instancier au sein de l’application. Pour cela, nous allons remplacer le UIViewController qui contient le label "Ecran d’accueil" par notre "MATableViewController". Dans le storyboard de l’application, commencez par supprimer le viewController existant. Maintenant, faites un glissé/déposé de l’objet "Table View Controller" depuis la collection d’objets vers le storyboard. Vous noterez que le précédent UIViewController a une apparence différente de notre UITableViewController. En effet, ce dernier dispose d’une tableView qui affiche les cellules. Maintenant, il nous faut associer ce nouveau UITableViewController à notre classe MATableViewController précédemment créée. Pour cela, sélectionnez le Table View Controller dans la scène du storyboard :
Une fois cela effectuée, allez dans l’identify inspector de l’élément et changez la classe du Table View Controller de UITableViewController (classe par défaut) à MATableViewController. Vous aurez aussi noté la flèche qui pointe vers notre MATableViewController. Cela indique que c’est notre viewController initial et donc qu’il sera affiché au lancement de l’application :
A ce stade, l’application affiche une liste vide. Voyons maintenant comment la remplir en récupérant des données !
Présentation de l’API RottenTomatoes
Nous avons choisi de récupérer les données cinématographiques depuis le site RottenTomatoes ( http://www.rottentomatoes.com ) qui possède une API publique. Le principe est simple : à l’aide de requêtes spécifiques, nous allons interroger le site et celui-ci va nous renvoyer les informations demandées au format JSON, c’est-à-dire sous forme d’un ensemble de clés et de valeurs qui représentent un objet ou une liste d’objets.
C’est un service web RESTful destiné à faciliter l’accès aux données du site. Tous les appels se feront depuis l’URI de base http://api.rottentomatoes.com/api/public/v1.0, en s’authentifiant grâce à une API_KEY. Le schéma d’appel est donc très simple : Base_URI / Path_To_Resource ? apikey=YOUR_API_KEY & key1=value1 & key2=value… avec key1 et key2 des paramètres et value1 et value2 leurs valeurs respectives.
Voici par exemple le lien pour récupérer la deuxième page de la liste des films qui vont bientôt sortir, chaque page ayant 20 films : http://api.rottentomatoes.com/api/public/v1.0/lists/movies/upcoming.json?apikey=[your_api_key]&page_limit=20&page=2
Pour plus d’informations sur l’utilisation de cette API, nous vous invitons à lire la documentation complète qui est disponible à cette adresse : http://developer.rottentomatoes.com/docs
Afin de pouvoir réaliser notre projet, il vous faut tout d’abord obtenir votre API_KEY, en créant un compte sur le site à l’adresse http://developer.rottentomatoes.com/member/register. Remplissez le formulaire et dans la section « Register Your New Application », donnez un nom à votre projet, une url et le type « Mobile Application ».
Formulaire de création de compte sur RottenTomatoes
Section "Register Your Application" du formulaire, qui permet d’obtenir la clé d’API
Vous recevrez alors un email de vérification pour finaliser la création de votre compte, qui contient un lien vers une page où vous pourrez trouver votre clé.
Récupération des données
Maintenant que vous avez votre clé d’API, nous allons pouvoir commencer à connecter l’application. Afin de bien séparer les fonctionnalités, nous allons créer un nouvel objet héritant de la classe NSObject qui gérera tous les appels à l’API RottenTomatoes. Dans XCode, faites Fichier -> Nouveau Fichier, sélectionnez "Cocoa Touch" dans la liste à gauche puis "Objective-C class". Vérifiez que la classe hérite bien de NSObject et nommez-la MADataSource.
Dans un premier temps, nous allons récupérer la liste des films du box office. Dans le fichier MADataSource.h, nous allons rajouter une property dataArray qui contiendra la liste des résultats et une méthode loadBoxOfficeData. Sous iOS, une property est définie par la syntaxe suivante:
@property (ATTRIBUTES_DE_LA_PROPRIETE) [IBOutlet] [Classe] [NOM_OBJET];
Nous ne nous attarderons pas sur les attributs des property, car cela pourrait être l’objet d’une exploration plus approfondie mais nous dirons simplement que, pour chaque property qui représente un élément visuel géré par le Storyboard, les attributs corrects doivent être "nonatomic, weak", pour les autres properties les attributs seront (dans la plupart des cas) "nonatomic, strong".
@interface MADataSource : NSObject @property (nonatomic, strong) NSArray *dataArray; -(void) loadBoxOfficeData; @end
Dans le fichier MADataSource.m, nous allons ajouter deux NSStrings statiques pour définir notre clé d’API et l’URI de base
static const NSString *kAPI_KEY = @"YOUR API KEY "; static const NSString *kBaseURI = @"http://api.rottentomatoes.com/api/public/v1.0/";
L’avantage de cette solution est de rassembler les différentes variables de configuration au même endroit et de pouvoir éviter les fautes de frappe lorsque nous allons les utiliser.
Passons maintenant aux choses sérieuses : la récupération des films du box office. D’après la documentation de l’API, la liste peut être obtenue à l’adresse lists/movies/box_office.json et deux paramètres peuvent être ajoutés : "limit", qui définit le nombre de films renvoyés et "country" qui permet de définir le pays qui nous intéresse.
Le principe que nous allons utiliser est simple : récupérer les données grâce à la fonction + (id)dataWithContentsOfURL:(NSURL *)aURL de la classe NSData puis les transformer en objets du kit de développement (NSArray ou NSDictionary) pour pouvoir les manipuler facilement grâce à la classe NSJSONSerialization prévue à cet effet.
La première méthode que nous allons créer sera notre constructeur d’URL. Elle prend en paramètre le chemin relatif pour la fonction à appeler ainsi qu’un dictionnaire de paramètres. Cela va nous permettre de créer les URLs pour nos différents appels en y ajoutant des paramètres. Elle pourra donc être réutilisée pour n’importe lequel de nos appels.
-(NSURL*) rottenTomatoesUrlForPath:(NSString*)relativePath params:(NSDictionary*) params { // Create a new mutable string starting with our base URI NSMutableString *urlString = [NSMutableString stringWithString:(NSString*)kBaseURI]; // Append the relative path and our api key [urlString appendString:relativePath]; [urlString appendFormat:@"?apikey=%@",kAPI_KEY]; // Append all params in the dictionary as key = obj [params enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { [urlString appendFormat:@"&%@=%@", key, obj]; }]; return [NSURL URLWithString:urlString]; }
Maintenant que nous pouvons contruire l’URL où sont les données qui nous intéressent, il faut les récupérer.
Ajoutez une nouvelle NSString constante au début du fichier MADataSource.m pour définir le chemin relatif de la requête "Box Office"
static const NSString *kBoxOfficePath = @"lists/movies/box_office.json";
Nous allons maintenant charger les données depuis le site et enregistrer la réponse dans notre liste dataArray. Nous allons récupérer le code pays de l’utilisateur puis former l’URL grâce à notre méthode.
Notre URL sera donc : http://api.rottentomatoes.com/api/public/v1.0/lists/movies/box_office.json?apikey=[your_api_key]&country=[user_country_code]&limit=20
-(void) loadBoxOfficeData { self.dataArray = [self boxOfficeArray]; } -(NSArray*) boxOfficeArray { // Retrieve the current user country code NSLocale *locale = [NSLocale currentLocale]; NSString *countryCode = [locale objectForKey: NSLocaleCountryCode]; // Create the params dictionary NSDictionary *params = @{@"country": countryCode, @"limit": @20}; // Load data from the properly formed URL NSData *moviesData = [NSData dataWithContentsOfURL:[self rottenTomatoesUrlForPath:(NSString*)kBoxOfficePath params:params]]; // Transform data into a NSDictionary with NSJSONSerialization NSError *error; NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:moviesData options:0 error:&error]; if (error) { NSLog(@"Error getting movies: %@", error.localizedDescription); } // The movie list is under the key 'movies' (cf API doc) in the response so only return this part return jsonDict[@"movies"]; }
Regardons un peu le contenu de la réponse du serveur :
{ "movies":[ movieObject1, movieObject2, ... ], "links": { "self":"http://api.rottentomatoes.com/api/public/v1.0/lists/movies/box_office.json?limit=2&country=fr", "alternate":"http://www.rottentomatoes.com/movie/box-office/" }, "link_template":"http://api.rottentomatoes.com/api/public/v1.0/lists/movies/box_office.json?limit={num-results}&country={country-code}" }
La liste des films est enregistrée dans la variable movies. C’est donc cette valeur qui nous intéresse.
Il ne nous reste plus qu’à préparer l’affichage des données. En effet, chaque film possède plusieurs propriétés, identifées par leur clé, qui contiennent les infos. Afin une fois de plus de bien séparer les fonctionnalités de l’application, le tableViewController n’est pas censé connaitre ces clés. Nous allons donc créer une méthode qui va renvoyer un dictionnaire avec 3 clés : kInfoTitle, kInfoSubtitle, kInfoImageURL dont les valeurs seront celles d’un des éléments de notre liste.
-(NSDictionary *) infoDictForItemAtIndex:(NSInteger)index { NSDictionary *baseDict = self.dataArray[index]; NSDictionary *returnDict = @{kInfoTitle: baseDict[@"title"], kInfoSubtitle: [baseDict[@"year"] description], kInfoImageURL: baseDict[@"posters"][@"thumbnail"]}; return returnDict; }
Afin de pouvoir utiliser cette méthode dans le tableViewController, il ne nous reste plus qu’à la déclarer dans MADataSource.h, sans oublier d’ajouter nos clés !
static const NSString *kInfoTitle = @"title"; static const NSString *kInfoSubtitle = @"subtitle"; static const NSString *kInfoImageURL = @"image"; @interface MADataSource : NSObject ... -(NSDictionary *) infoDictForItemAtIndex:(NSInteger)index; @end
Maintenant que notre dataSource est créé et fonctionnel, rajoutons le au tableViewController afin que ce dernier puisse accéder aux données des films :
#import "MADataSource.h" @interface MATableViewController : UITableViewController @property (nonatomic, strong) MADataSource *dataSource; @end
Il ne nous reste plus qu’à récupérer les données une fois que le tableViewController se charge. Pour cela, il suffit d’allouer la dataSource et de lancer le téléchargement des données dans le viewDidLoad du tableViewController :
@implementation MATableViewController - (void)viewDidLoad { [super viewDidLoad]; self.dataSource = [[MADataSource alloc] init]; [self.dataSource loadBoxOfficeData]; } ... @end
Affichage des données dans le tableau
Une fois toutes les données téléchargées, nous sommes maintenant en mesure de les présenter dans notre UITableViewController. Le tableView contiendra une liste de films où chaque item présentera l’affiche du film, le titre et l’année d’émission, comme le montre l’image ci-dessous.
Sous iOS, chaque élément d’une tableView s’appelle une cellule et doit être de type UITableViewCell. Grâce au storyboard précédemment créé, nous pouvons configurer l’apparence de la cellule directement dans l’éditeur d’interface sans que notre code ait à gérer le positionnement des éléments.
Tout d’abord, nous devons créer la classe de notre cellule. Dans Xcode, Cliquons sur File → New → File → Objective-C class et remplissions les valeurs suivantes:
- Class: MAMovieCell
- Subclass of: UITableViewCell
Nous pouvons maintenant cliquer sur Next et enregistrer. Xcode a créé deux nouveaux fichiers : MAMovieCell.h et MAMovieCell.m qui contiennent respectivement la déclaration et les implémentations de notre notre objet cellule.
Dans le fichier MAMovieCell.h, ajoutez trois éléments : deux labels (titre et année) et une imageView (pour l’affiche du film).
@property (nonatomic, weak) IBOutlet UILabel *titleLabel; @property (nonatomic, weak) IBOutlet UILabel *subtitleLabel; @property (nonatomic, weak) IBOutlet UIImageView *thumbnail;
L’attribut IBOutlet indique que la propriété sera gérée par l’éditeur d’interface (Interface Builder, d’où le préfixe "IB").
Maintenant que nous avons créé les propriétés de l’objet, nous pouvons passer à la définition de leur aspect et de positionnement. Ouvrons le Storyboard une fois de plus. À l’intérieur du tableViewController, nous allons cliquer sur la région vide juste en dessous de "Prototype cells" : cette région représente notre cellule, mais elle est encore vide.
Pour la configurer, changeons la classe de la cellule en saisissant MAMovieCell, comme montré dans l’image ci-dessous.
Maintenant il faudra cliquer sur le quatrième onglet de la gauche et mettre la valeur "Identifier" à "MovieCell". Cette information nous sera très utile un peu plus loin.
Nous pouvons maintenant ajouter les éléments visuels de notre cellule : dans la bibliothèque d’objets, recherchez imageView et faites-la glisser sur la cellule vide. Une fois l’imageView ajoutée à la cellule, nous pouvons la redimensionner et la déplacer comme souhaité.
Une autre étape fondamentale est de dire à Xcode que l’imageView que nous avons ajoutée est celle définie à travers la property dans notre code.
Pour ce faire, il faut cliquer sur "Movie Cell" dans la liste à gauche de Xcode et sélectionner le dernier onglet dans le menu de droite.
Xcode va maintenant montrer les propriétés de sortie de notre cellule (vous vous souvenez de l’attribut IBOutlet que nous avons ajouté ci-dessus ?) et vous devriez être en mesure de voir "thumbnail", "subtitleLabel" et "titleLabel". Nous pouvons maintenant connecter la property "thumbnail" à l’imageView: cliquez sur le petit cercle à droite de la propriété «thumbnail» et, avec le curseur, tracez une ligne depuis ce cercle vers l’imageView comme le montre l’image ci-dessous.
Un IBOutlet connecté aura un rectangle arrondi autour du nom de la propriété.
Faisons de même pour les deux libellés, en ajoutant deux UILabels sur la cellule et reliant leur IBOutlet à l’élément respectif.
L’image ci-dessous montre à quoi le storyboard devrait ressembler.
Notre travail sur le storyboard est maintenant terminé. Revenons donc au "vrai" codage!
Ouvrons le MATableViewController et importons le .h de la MAMovieCell :
#import "MAMovieCell.h" @implementation MATableViewController ... @end
Maintenant, ajoutons (ou remplaçons) les trois méthodes qui géreront ensemble dataSource, tableViewController et cellules.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { // Return the number of sections. return 1; }
Cette méthode informe la tableView du nombre de sections qui doivent être affichées. Puisque nos éléments seront tous affichés sur une seule section, nous renvoyons "1" simplement.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // Return the number of rows in the section. return [self.dataSource.dataArray count]; }
La méthode ci-dessus communiquera à la tableView le nombre de cellules qui doivent être affichées. Les informations sont extraites à partir de notre source de données : on renvoi ainsi le nombre d’éléments contenus dans notre "dataArray".
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"MovieCell"; MAMovieCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; // Configure the cell... NSDictionary *infoDict = [self.dataSource infoDictForItemAtIndex:indexPath.row]; cell.titleLabel.text = infoDict[kInfoTitle]; cell.subtitleLabel.text = infoDict[kInfoSubtitle]; cell.thumbnail.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:infoDict[kInfoImageURL]]]]; return cell; }
Enfin, le code ci-dessus permet de configurer la cellule. Voici quelques détails supplémentaires à ce sujet :
MAMovieCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
Cette ligne instancie une MAMovieCell en utilisant un "Identifier" spécifié qui, dans notre cas est "MovieCell". Souvenez-vous, dans le Storyboard, nous avons mis cette valeur juste après avoir saisi le nom de la classe de la cellule et c’est bien grâce à ce paramètre que le système sera en mesure d’instancier la classe pour nous.
NSDictionary *infoDict = [self.dataSource infoDictForItemAtIndex:indexPath.row];
Ici, nous avons stocké dans la variable infoDict l’information contenue dans notre dataSource.
cell.titleLabel.text = infoDict[kInfoTitle]; cell.subtitleLabel.text = infoDict[kInfoSubtitle]; cell.thumbnail.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:infoDict[kInfoImageURL]]]];
Et, enfin, ici nous avons attribué les propriétés "texte" de nos libellés ainsi que l’"image" de l’imageView. Les valeurs sont de nouveau extraites du dataSource et, plus précisément, de la variable infoDict que nous venons de créer.
Après une compilation, voici à quoi ressemble notre application :
Conclusion
Vous avez désormais les bases pour réaliser une application connectée. Vous pouvez d’ores et déjà implémenter différents appels et gérer l’affichage des réponses.
Dans le prochain article, nous verrons comment afficher les détails d’un film et réagir à différentes interactions de l’utilisateur. D’ici là, bon code et à la prochaine fois !