I. Introduction▲
Dans ce tutoriel, nous allons créer une application simple de lecture de flux RSS. L'application sera basée sur un design « master / detail », où la vue principale affiche la liste des flux disponibles et la vue détaillée affiche les pages Web correspondantes.
Le cœur de l'application est la classe NSXMLParser. NSXMLParser est l'analyseur XML inclus par défaut avec le SDK iPhone. NSXMLParser est un analyseur SAX ce qui signifie qu'il a un comportement événementiel lors de l'analyse des fichiers XML. À chaque fois que l'analyseur a fini le traitement d'une partie du fichier XML, il appelle une méthode spécifique de l'analyseur.
II. Créer l'application▲
Ouvrez Xcode et créez un nouveau projet en choisissant le modèle d'application « master / detail » comme illustré ci-dessous :
Dans l'écran suivant, saisissez « RssReader » comme le nom de programme et « com.appcoda » dans le champ du nom de l'entreprise. Ne pas oublier de sélectionner les options « Use Storybooards » et « Use Automatic Reference Counting ». Appuyez sur le bouton « Next ».
III. Définir l'interface utilisateur▲
Sélectionnez le fichier MainStoryboard.storyboard avec le navigateur Xcode pour afficher le Storyboard dans le volet de l'éditeur.
Comme vous pouvez le voir, nous avons déjà tous les éléments dont nous avons besoin pour notre lecteur :
- une barre de navigation pour aller en avant et en arrière dans les flux ;
- une vue globale en forme de table pour afficher la liste des flux disponibles ;
- une vue détaillée qui contiendra une vue Web pour afficher le flux RSS sélectionné.
Toutefois, nous avons encore besoin de faire quelques changements dans le storyboard pour avoir une interface utilisateur entièrement fonctionnelle.
Tout d'abord, sélectionnez le contrôleur de la vue « master » et changez le titre de la barre de navigation de « Master » pour « Stories » ou à tout autre titre que vous préférez. Ensuite, cliquez sur le bouton « Assistant Editor » pour ouvrir le code source associé à notre vue « Master » (APPMasterViewController.h). Créez un « IBOutlet » pour notre table (glisser de la UITableView vers le code source) :
- dans le champ de connexion, nous devons choisir Outlet ;
- pour le champ « Name », nous choisissons tableView ;
- pour le champ « Type », nous choisissons UITableView ;
- et enfin, pour le champ « Storage », nous sélectionnons « Strong ».
Cela devrait créer un « IBOutlet » comme ceci :
@property
(
strong
, nonatomic
) IBOutlet UITableView *
tableView;
Maintenant, sélectionnez le contrôleur de la vue « detail » et changez de nouveau le titre de la barre de navigation. Au lieu de « detail », mettez « Content ». Ensuite, nous devons retirer l'étiquette dans le centre de la vue, puisque nous n'allons pas l'utiliser. Ne pas oublier d'enlever sa propriété « IBOutlet » du fichier APPDetailViewController.h et de supprimer la propriété « detailItem » aussi. Enfin, faites un glisser/déposer d'un objet « UIWebView » depuis la bibliothèque d'objets vers le contrôleur de la vue « detail ». Assurez-vous que l'affichage Web occupe tout l'espace disponible.
Encore une fois, nous devons créer un « IBOutlet » dans UIWebView. En utilisant la procédure décrite ci-dessus, glissez un « outlet » vers le fichier APPDetailViewController.h en le nommant « webView ». Ajoutez aussi un autre « @property » de type NSString avec le modificateur « copy ». Cette propriété contiendra l'URL de du flux actuellement sélectionné. Si vous avez tout fait correctement, le fichier APPDetailViewController.h devrait ressembler à cela :
#
import
<UIKit/UIKit.h>
@interface
APPDetailViewController : UIViewController
@property
(
copy, nonatomic
) NSString
*
url;
@property
(
strong
, nonatomic
) IBOutlet UIWebView *
webView;
@end
IV. Implémenter la vue générale▲
Dans le fichier APPMasterViewController.m, remplacer la déclaration @interface par le code suivant :
@interface
APPMasterViewController (
) {
NSXMLParser
*
parser;
NSMutableArray
*
feeds;
NSMutableDictionary
*
item;
NSMutableString
*
title;
NSMutableString
*
link;
NSString
*
element;
}
@end
Dans cette section, nous déclarons plusieurs variables :
- parser est l'objet qui va télécharger et analyser le XML du flux RSS ;
- feeds est un tableau « mutable » qui contient la liste des flux téléchargés ;
- item est un dictionnaire « mutable » qui va contenir les détails du flux, dans note cas, son nom et son URL ;
- et enfin, element pour savoir quel élément est en cours d'analyse par l'objet NSXMLParser.
Dans la fonction « viewDidLoad » nous devons initialiser l'objet NSXMLParser. Par souci de simplicité, dans le présent exemple l'URL du flux RSS est codée en dur. Nous utilisons simplement le flux « hot news feed » d'Apple (http://images.apple.com/main/rss/hotnews/hotnews.rss). Dans une application de production, vous devez permettre à l'utilisateur de changer cette adresse depuis l'interface utilisateur.
-
(
void
)viewDidLoad {
[super
viewDidLoad];
feeds =
[[NSMutableArray
alloc] init];
NSURL
*
url =
[NSURL
URLWithString:@"http://images.apple.com/main/rss/hotnews/hotnews.rss"
];
parser =
[[NSXMLParser
alloc] initWithContentsOfURL:url];
[parser setDelegate:self
];
[parser setShouldResolveExternalEntities:NO
];
[parser parse];
}
Ensuite, supprimez la méthode « insertNewObject » puisque nous ne permettrons pas à l'utilisateur d'ajouter des flux manuellement et remplacez les méthodes de gestion de la table par le code suivant :
-
(
NSInteger
)numberOfSectionsInTableView:(
UITableView *
)tableView {
return
1
;
}
-
(
NSInteger
)tableView:(
UITableView *
)tableView numberOfRowsInSection:(
NSInteger
)section {
return
feeds.count;
}
-
(
UITableViewCell *
)tableView:(
UITableView *
)tableView cellForRowAtIndexPath:(
NSIndexPath
*
)indexPath {
UITableViewCell *
cell =
[tableView dequeueReusableCellWithIdentifier:@"Cell"
forIndexPath:indexPath];
cell.textLabel.text =
[[feeds objectAtIndex:indexPath.row] objectForKey: @"title"
];
return
cell;
}
Le seul élément nouveau, c'est la ligne de code suivante, où nous définissons le titre de la cellule courante avec le nom du flux RSS :
cell.textLabel.text =
[[feeds objectAtIndex:indexPath.row] objectForKey: @"title"
];
Retirez aussi les méthodes « canEditRowAtIndexPath » et « commitEditingStyle », puisque nous n'avons pas besoin d'elles pour cette application.
V. Implémenter le Parser XML▲
Ensuite, nous devons implémenter les méthodes du parser XML. Pour ce faire, nous devons dire au compilateur que la classe « ENTMasterViewController » implémente l'interface « NSXMLParserDelegate ». Ouvrez le fichier « ENTMasterViewController.h » et remplacez la définition de la classe par :
@interface
ENTMasterViewController : UITableViewController <
NSXMLParserDelegate
>
À chaque fois que l'analyseur trouve un nouvel élément, il appelle la méthode didStartElement de la classe. Dans cette méthode, nous devons vérifier que l'élément trouvé est un « item », et si c'est le cas, nous allouons les variables pour stocker l'élément.
(
void
)parser:(
NSXMLParser
*
)parser didStartElement:(
NSString
*
)elementName namespaceURI:(
NSString
*
)namespaceURI qualifiedName:(
NSString
*
)qName attributes:(
NSDictionary
*
)attributeDict {
element =
elementName;
if
(
[element isEqualToString:@"item"
]) {
item =
[[NSMutableDictionary
alloc] init];
title =
[[NSMutableString
alloc] init];
link =
[[NSMutableString
alloc] init];
}
}
Ensuite, le parser appelle la fonction pour chaque nouveau caractère lu. C'est pourquoi nous devons utiliser des chaînes « mutables », puisque nous devons ajouter les nouveaux caractères trouvés aux précédents. Dans notre cas, nous sommes intéressés par les éléments « title » et « link » mais nous pourrions également stocker des informations de « date » ou « summary ».
-
(
void
)parser:(
NSXMLParser
*
)parser foundCharacters:(
NSString
*
)string {
if
(
[element isEqualToString:@"title"
]) {
[title appendString:string];
}
else
if
(
[element isEqualToString:@"link"
]) {
[link appendString:string];
}
}
Lorsque le parser rencontre la fin d'un élément, il appelle la méthode « didEndElement ». Dans ce cas, nous ajoutons simplement le nouvel objet à l'ensemble des objets.
-
(
void
)parser:(
NSXMLParser
*
)parser didEndElement:(
NSString
*
)elementName namespaceURI:(
NSString
*
)namespaceURI qualifiedName:(
NSString
*
)qName {
if
(
[elementName isEqualToString:@"item"
]) {
[item setObject:title forKey:@"title"
];
[item setObject:link forKey:@"link"
];
[feeds addObject:[item copy]];
}
}
Et lorsque le parser arrive à la fin du document, il appelle la méthode « parserDidEndDocument » et dans ce cas, ce que nous avons à faire est d'informer UITableView de se réafficher, puisque maintenant nous avons toutes les données.
-
(
void
)parserDidEndDocument:(
NSXMLParser
*
)parser {
[self
.tableView reloadData];
}
VI. Implémenter la vue détaillée▲
Nous devons trouver un moyen d'informer le contrôleur de vue « Detail » de l'URL du flux que nous voulons afficher. Pour ce faire, nous utilisons la méthode « prepareForSegue » du contrôleur de vue « master » où nous définissons l'URL avec la méthode setUrl de destintionViewController :
-
(
void
)prepareForSegue:(
UIStoryboardSegue *
)segue sender:(
id
)sender {
if
(
[[segue identifier] isEqualToString:@"showDetail"
]) {
NSIndexPath
*
indexPath =
[self
.tableView indexPathForSelectedRow];
NSString
*
string =
[feeds[indexPath.row] objectForKey: @"link"
];
[[segue destinationViewController] setUrl:string];
}
}
La dernière étape consiste à modifier le fichier « APPDetailViewController.m ». La vue « detail » est très simple, il suffit de fournir la méthode « viewDidLoad » ci-dessous et de supprimer les autres méthodes :
-
(
void
)viewDidLoad {
[super
viewDidLoad];
NSURL
*
myURL =
[NSURL
URLWithString: [self
.url stringByAddingPercentEscapesUsingEncoding:
NSUTF8StringEncoding
]];
NSURLRequest
*
request =
[NSURLRequest
requestWithURL:myURL];
[self
.webView loadRequest:request];
}
Cette méthode demande à la webView d'afficher le contenu du flux sélectionné. Pour cela, nous créons d'abord un NSURL avec la chaîne que nous avons, mais en prenant garde aux caractères qui peuvent créer des problèmes dans un URK en utilisant stringByAddingPercentEscapesUsingEncoding. Et puis, nous créons un NSURLRequest pour télécharger la page Web avec le flux.
Si vous n'avez pas fait d'erreur, vous devriez être capable de compiler et exécuter l'application lecteur de flux RSS dans le simulateur.
VII. Télécharger les sources▲
J'espère que vous avez apprécié ce tutoriel. Vous devriez maintenant avoir une idée de base concernant la lecture de flux RSS en utilisant NSURLRequest et NSXMLParser. Pour votre information, vous pouvez télécharger le code source complet ici.
Nous allons voir d'autres choses plus intéressantes encore dans les tutoriels à venir. Comme toujours, laissez-nous le commentaire et partagez votre réflexion sur ces tutoriels.
VIII. Remerciements▲
Nous remercions, Simon ng, de nous avoir aimablement autorisé à publier son article. Cet article est une traduction autorisée dont le texte original peut être trouvé sur Appcoda.com. Nous remercions aussi ram-0000 pour sa traduction, Seelass pour sa relecture technique ainsi que jacques_jean pour sa relecture orthographique.
Les commentaires et les suggestions d'amélioration sont les bienvenus, alors, après votre lecture, n'hésitez pas : Commentez .