Nous allons expliquer par ce billet comment lire du code JSON sous iPhone tout en gérant d’éventuelles erreurs. Nous ne ferons que présenter la librairie avec un exemple clair et concis qui peut facilement se customiser selon les besoins.
MAJ 3 Octobre 2010 : Modifications effectuées pour supporter la 2.3.1 de la librairie utilisée.
Pourquoi du JSON ?
Même si à l’heure actuelle les réseaux mobiles ne sont pas encore trop saturés en France (contrairement à nos amis Anglophones), il est bon de choisir un moyen relativement léger pour faire transiter des données. Le XML, quand bien même très répandu et facile à utiliser, n’est pas forcément très léger. Voici un rapide exemple pour le prouver (sans en-tête de charset etc).
Version XML
Au petit Gecko
10 Rue du Soleil, Mer du Paradis
La Spéciale
0.45
Gourmandise du Gecko
0.30
Version JSON
{ "bakery":
{
"name": "Au petit Gecko",
"adress": "10 Rue du Soleil, Mer du Paradis",
"candies": {
"candy": [
{"name": "La Spéciale", "price": "0.45"},
{"name": "Gourmandise du Gecko", "price": "0.30"}
]
}
}
}
Quelques statistiques
Comme on peut le voir, le JSON est bien plus compact. On aurait pu réduire un peu plus le XML en mettant plus d’attributs dans les éléments, mais c’est selon les cas. Nous obtenons 311 caractères pour le XML contre 268 caractères pour le JSON. Soit un gain de d’environ 14%. Notre exemple n’a qu’une valeur modérée puisqu’il n’y a que quelques lignes. Toutefois si nous venions à rajouter 100 bonbons (au lieu de 2 actuellement), nous aurions un gain d’environ 35/40%. Donc selon les données le gain est plus ou moins fort et surement non-négligeable lorsqu’il s’agit d’une connexion à faible débit ou s’il faut transférer beaucoup de données.
Toutefois nous ne prenons pas tout en compte, nous pourrions aussi venir à comparer le temps de parsing. Mais ce n’est pas le but ici, donc nous passerons sur ce coup-là :-]
Installer JSON pour iPhone
Télécharger le projet
Avant de pouvoir utiliser du JSON sur iPhone il vous faut d’abord télécharger la librairie qui pourra l’analyser. Allez sur le projet GitHub à cette adresse et téléchargez le dernier zip||dmg. Cela a changé puisqu’avant le projet était hébergé sur Google Code. A l’heure de la modification de ce tutorial, la version téléchargée est la 2.3.1.
L’ajouter au projet xCode
Décompressez l’archive et ajoutez le dossier “Classes” à votre projet xCode. Vous devriez même faire une copie du dossier Classes sur votre bureau, le renommer en “json” (ou autre), puis le déplacer dans vos sources (sans oublier de cocher la case pour que xCode copie les fichiers dans votre projet). Puis il vous suffit de lier la librairie à votre projet avec un :
#import "JSON.h"
Exemple JSON
Nous partons du principe que vous avez récupéré le code JSON via une requête HTTP (nous ferons bientôt un billet à ce propos) ou bien dans un fichier.
Etape par étape
Dans un premier temps nous déclarons les variables utilisées :
// Vars SBJsonParser *json; NSError *jsonError; NSDictionary *jsonResults; NSString *response;
- La première variable (json) permet de procéder au traitement de la chaîne de texte contenant le code JSON.
- La deuxième (jsonError) est utilisée pour stocker une éventuelle erreur lors se la procédure.
- La troisième (jsonResults) contient la liste des objets après le traitement
- Et enfin la dernière (response) contient votre code à parser. Ici nous reprendrons celui précisé en haut.
Puis nous initialisons la variable json :
response = @"{"bakery":{"name":"AupetitGecko","adress":"10RueduSoleil,MerduParadis","candies":{"candy":[{"name":"LaSpéciale","price":"0.45"},{"name":"GourmandiseduGecko","price":"0.30"}]}}}";
// Init JSON
json = [ [ SBJsonParser new ] autorelease ];
Et enfin nous procédons à la lecture de la variable contenant le code JSON (response) :
// Get result in a NSDictionary jsonResults = [ json objectWithString:response error:&jsonError ];
Si une erreur est survenue alors la variable jsonResults sera à “nil”. Il nous suffit alors de procéder ainsi :
// Check if there is an error
if (jsonResults == nil) {
NSLog(@"Erreur lors de la lecture du code JSON (%@).", [ jsonError localizedDescription ]);
} else {
// Do some stuff
}
Il ne nous reste plus qu’à parser le code JSON (voir l’exemple ci-dessus) :
// Check if there is an error
if (jsonResults == nil) {
NSLog(@"Erreur lors de la lecture du code JSON (%@).", [ jsonError localizedDescription ]);
} else {
NSArray *candiesList;
NSDictionary *bakery = [ jsonResults objectForKey:@"bakery" ];
NSLog(@"Nom : %@", [ bakery objectForKey:@"name" ]);
NSLog(@"Adresse : %@", [ bakery objectForKey:@"adress" ]);
NSLog(@"Bonbons :");
candiesList = [ [ bakery objectForKey:@"candies" ] objectForKey:@"candy" ];
for (NSDictionary *candy in candiesList) {
NSLog(@"tNom=%@ et Prix=%@", [ candy objectForKey:@"name" ],
[ candy objectForKey:@"price" ]);
}
}
Notez que nous avons ici stocké l’ensemble des bonbons dans un NSArray et non un NSDictionnary. Le NSArray contient bien au final un ensemble de NSDictionnary que l’on peut parcourir sans problème.
Tout le code
Et pour finir l’ensemble des morceaux assemblés bout à bout :
// Vars
SBJsonParser *json;
NSError *jsonError;
NSDictionary *jsonResults;
response = @"{"bakery":{"name":"AupetitGecko","adress":"10RueduSoleil,MerduParadis","candies":{"candy":[{"name":"LaSpéciale","price":"0.45"},{"name":"GourmandiseduGecko","price":"0.30"}]}}}";
// Init JSON
json = [ [ SBJsonParser new ] autorelease ];
// Get result in a NSDictionary
jsonResults = [ json objectWithString:response error:&jsonError ];
// Check if there is an error
if (jsonResults == nil) {
NSLog(@"Erreur lors de la lecture du code JSON (%@).", [ jsonError localizedDescription ]);
} else {
NSArray *candiesList;
NSDictionary *bakery = [ jsonResults objectForKey:@"bakery" ];
NSLog(@"Nom : %@", [ bakery objectForKey:@"name" ]);
NSLog(@"Adresse : %@", [ bakery objectForKey:@"adress" ]);
NSLog(@"Bonbons :");
candiesList = [ [ bakery objectForKey:@"candies" ] objectForKey:@"candy" ];
for (NSDictionary *candy in candiesList) {
NSLog(@"tNom=%@ et Prix=%@", [ candy objectForKey:@"name" ],
[ candy objectForKey:@"price" ]);
}
}



