Main Contents

[Objective-c] Application iPhone, XML et UITableView

avril 26, 2009

Nous allons donc poursuivre le tutorial précédent qui permettait de parser un fichier XML, mais qui n’en faisait rien de spécial. Ici nous allons voir comment remplir un UITableView et afficher les informations d’un contact.

I) Introduction

Si vous avez suivi le tutorial sur comment parser un fichier XML, vous devez avoir une application de type Navigation-Based.
C’est à dire que votre application à 2 fichiers xib, MainWindow.xib et RootViewController.xib.

II) UITableView

Première chose, nous allons remplir notre UITableView. Dans RootViewController.h ajouter un NSMutableArray.

//RootViewController.h
@interface RootViewController : UITableViewController {
	NSMutableArray *tableau;
}

Il faut maintenant remplir ce tableau. Nous allons modifier notre boucle dans RootViewController.m pour qu’elle ajoute un objet de type Contact dans chaque case du tableau.

//RootViewController.m
- (void)viewDidLoad {
	tableau = [[NSMutableArray alloc] init];
	NSURL *url = [NSURL URLWithString: @"http://www.jkraft.fr/testXml.xml"];
	XMLToObjectParser *myParser = [[XMLToObjectParser alloc] parseXMLAtURL:url toObject:@"Contact" parseError:nil];
 
	for(int i = 0; i < [[myParser items] count]; i++) {
		Contact *new = [[Contact alloc] init];
		new = (Contact *)[[myParser items] objectAtIndex:i];
		[tableau addObject:new];
		[new release];
	}
   [super viewDidLoad];
}

Toujours dans RootViewController.m nous allons décommenter quelques fonctions qui concerne le UITableView et modifier certaines. Vous devez arriver à ce résultat.

//RootViewController.m
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}
 
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [tableau count];
}
 
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
	NSString *ligneTableau = [NSString stringWithFormat:@"%@ %@", [[tableau objectAtIndex:indexPath.row] nom],[[tableau objectAtIndex:indexPath.row] prenom]];
	cell.text=ligneTableau;	// Configure the cell.
    return cell;
}

Ligne 8, on indique au TableView combien de ligne il aura, c’est à dire combien d’élément il y a dans mon tableau. Et ligne 20-21 je concatène le nom et le prénom et je l’écris dans la cellule du TableView. Compiler et éxécuter l’application et vous devriez avoir quelque chose qui ressemble à ça si vous utilisez mon fichier XML.

UItableView

III) La fiche contact

Maintenant que nous avons la liste des contacts nous aimerions pouvoir en choisir un et afficher le reste des informations.
D’abord ajoutez une nouvelle classe de type UIViewController SubClass et nommez la ContactViewController. Vous avez donc 2 nouveaux fichiers, ContactViewController.h et ContactViewController.m
Nous voulons afficher nos 4 informations, on va donc créer 4 IBOutlets de type UILabel et un champs MonContact de type Contact qui contiendra notre objet courant. N’oubliez pas d’ajouter le Contact.h pour que le compilateur sache ce qu’est l’objet Contact.

//ContactViewController.h
#import
#import "Contact.h"
 
@interface ContactViewController : UIViewController {
 
	IBOutlet UILabel *nom;
	IBOutlet UILabel *prenom;
	IBOutlet UILabel *tel;
	IBOutlet UILabel *email;
	Contact *MonContact;
 
}
 
@property (nonatomic, retain) UILabel *nom;
@property (nonatomic, retain) UILabel *prenom;
@property (nonatomic, retain) UILabel *tel;
@property (nonatomic, retain) UILabel *email;
@property (nonatomic, retain) Contact *MonContact;
@end
//ContactViewController.m
#import "ContactViewController.h"
 
@implementation ContactViewController
@synthesize  nom,prenom,tel, email , MonContact;
 
- (void)viewDidLoad {
	prenom.text=MonContact.prenom;
	tel.text=MonContact.tel;
	nom.text=MonContact.nom;
	email.text=MonContact.email;
    [super viewDidLoad];
}

Et voilà, il ne reste plus qu’à définir la vue. Ajouter donc un nouveau fichier de type View Xib dans l’onglet User Interface avec le nom : ContactView.xib. Ajouter des labels, et reliez les au IBOutlets pour arriver à ceci.

liaison

Il reste une dernière chose à faire, car si vous compilez, lorsque vous cliquez sur un des éléments du TableView rien ne se passe. Il faut pour cela, modifier une dernière fois le fichier RootViewController.m et rajouter cette fonction.

// Override to support row selection in the table view.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // Navigation logic may go here -- for example, create and push another view controller.
	ContactViewController *contactViewController = [[ContactViewController alloc] initWithNibName:@"ContactView" bundle:nil];
	contactViewController.MonContact=[tableau objectAtIndex:indexPath.row];
	self.navigationItem.title=[[tableau objectAtIndex:indexPath.row] nom];
	[self.navigationController pushViewController:contactViewController animated:YES];
	[contactViewController release];
}

Ligne 5 on affecte l’objet Contact sélectionné dans contactViewController.
Ligne 6, on affiche dans la NavigationBar le nom du contact sélectionné.
Compilez et voilà. Nous affichons les détails pour chaqu’un des contacts de votre fichier XML!
Téléchargez les fichiers sources si vous avez un soucis.

resultat

Catégorie(s): Développement, Iphone, Objective-C, Tutorial | Comments (26)

26 Comments

  1. Philippe Guitard (1 comments) mai 4, 2009 @ 15 h 17 min

    On peut même supprimer un peu plus de code en utilisant les « bindings » dans Interface Builder, mais j’imagine que ce sera le sujet de la troisième partie de ce tutoriel?

    A quand une version vidéo? Nous serions heureux de la publier sur CocoaCast.com.

    Amicalement,

    ~Philippe

  2. kraft (36 comments) mai 4, 2009 @ 15 h 35 min

    Et bien, je suppose qu’on peut l’améliorer. Ce n’est pas prévu pour le moment, mais je suis preneur de tous conseils !

  3. Alan (1 comments) mai 12, 2009 @ 15 h 23 min

    Super tuto, très claire et tres simple à utiliser. Un grand merci à toi!!!

  4. DuMe (1 comments) juin 27, 2009 @ 16 h 03 min

    Super, tes tutos vont très certainement m’aider énormément! 😉

  5. Medhi Naitmazi (3 comments) juin 30, 2009 @ 10 h 56 min

    Merci jerome, au fait je n ai toujours pas eu le temps de le faire, mais je t’ai emailé, bonne journée !

  6. pun1ch3ur (1 comments) juillet 1, 2009 @ 20 h 02 min

    Bonsoir,

    J’ai un problème a la compilation du code.

    Quand je compile j’ai 3 erreurs :

    @synthesize window;
    error : @synthesize property must be in implementation context

    @synthesize navigationController;
    error : @synthesize property must be in implementation context

    – (void)applicationDidFinishLaunching:(UIApplication *)application {
    fatal error : method definition not in @implementation context

    Quelqu’un aurait-il une idée d’ou peut provenir mon erreur.

    Cordialement,
    pun1ch3ur

  7. Kiki (1 comments) juillet 2, 2009 @ 9 h 56 min

    Bonjour j’ai un souci sur la derniere partie, pour afficher les infos du contacts j’ai une erreur lorsque je clique sur une cellule :
    Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘-[UIViewController _loadViewFromNibNamed:bundle:] loaded the « ContactView » nib but the view outlet was not set.
    Je suppose que l’erreur viens de mon fichier xib mais je ne voit pas. Ce serait possible d’avoir les sources ?

  8. kraft (36 comments) juillet 8, 2009 @ 7 h 54 min

    C’est surement parce que tu n’as pas lié un élément dans Interface Builder!

  9. Seb (1 comments) juillet 13, 2009 @ 9 h 30 min

    J’ai exactement le même soucis que Kiki. Et j’ai beau faire et refaire ce tuto je n’arrive pas à afficher la vue avec le détail des informations.

    Merci Kraft pour l’info mais perso je ne vois du tout à quoi c’est dû.

    Quelqu’un aurait une idée svp?

  10. jdelgoulet (1 comments) juillet 26, 2009 @ 1 h 21 min

    malheureusement non , philippe … L’OS de l’iPhone ne gère pas les bindings comme le fait Mac OS X … du moins pour l’instant 😉

  11. potsky (1 comments) septembre 25, 2009 @ 14 h 55 min

    Pourquoi ça n’affiche pas le détail du contact ?

    Dans son code, on appelle le nouveau ViewController de cette manière :

    ContactViewController *contactViewController = [[ContactViewController alloc] initWithNibName:@ »ContactView » bundle:nil];

    Quand vous avez crée le nouveau ViewController, vous avez cliqué sur le bouton « Créer aussi un fichier XIB » que XCode a appelé ContactViewController or dans le tutoriel, on le crée à la main et on l’appelle ContactView.

    Donc pour appeler le ViewController, il faut plutôt écrire :

    ContactViewController *contactViewController = [[ContactViewController alloc] initWithNibName:@ »ContactViewController » bundle:nil];

    🙂

  12. Pacha (1 comments) novembre 17, 2009 @ 12 h 04 min

    Superbe TûT !!!!
    C’est le premier qui m’a permit de comprendre l’intégralité du Process d’implémentation.

    Cependant ca ne marche pas chez moi car ca ne veut pas remplir le tableau « tableau » en mode debug je vois bien l’objet « new » se remplir mais n’intègre pas l’objet « tableau »
    De plus je ne passe pas n’ont plus dans la partie concaténation du nom et prénom.

    Quelqu’un a une idée que je puisse enfin finaliser un projet 🙂

    Encore merci et bonne continuation

  13. Nico (1 comments) novembre 24, 2009 @ 18 h 13 min

    Pour Kiki et Seb,
    j’ai eu le même problème sur le click d’une cellule.
    en fait, à la création de ton objet « ContactViewController », il est hérité de « UITableViewController » et en fait il faut qu’il hérite de « UIViewController ».
    Tout simplement.
    Bonne continuation

  14. Sawyeur (1 comments) janvier 8, 2010 @ 13 h 47 min

    Bonjour,

    Merci pour le tuto !

    J’ai tout de même une question :

    Comment atteindre un attribut d’un noeud ?

    exemple :

    Merci d’avance 🙂

    Sawyeur.

  15. JLP (4 comments) mars 3, 2010 @ 11 h 07 min

    Bjr, merci pour ce tuto
    Ttf j’ai un pb.
    J’ai bien fait les 2 fichiers ContactViewController et le ContactView.xib.
    Mais dans IB, je n’arrive pas a voir mes IBOutlet…
    J’ai manqué quoi ?

  16. JLP (4 comments) mars 3, 2010 @ 11 h 18 min

    … 1000 excuses pour le bruit, je viens de trouver!
    Réponse pour ceux qui ont cherché comme moi:

    Dans IB, il faut indiquer que la classe ContactViewController va controler ContactView.xib
    Cela se fait dans l’Identity inspecteur.
    Et iPhonez bien

  17. JLP (4 comments) mars 3, 2010 @ 15 h 32 min

    Enfin un tuto pédagogique qui me fait bien avancer!
    Mais, je voudrais savoir s’il est possible de faire une saisie dans ContactView pour faire la maj d’un contact?
    Merci

  18. Pierre (5 comments) mai 3, 2010 @ 10 h 22 min

    Merci pour ce tutoriel fort utile qui va être la base d’une application client/serveur dialoguant avec une API.

    Bonne continuation,
    Pierre

  19. jam (1 comments) mai 8, 2010 @ 14 h 56 min

    Bonjour,
    dans un premier temps merci pour ce tutoriel bien expliqué. Auriez vous une piste pour pouvoir afficher que les données relatives à ce que l’utilisateur voudrait. Ex : l’utilisateur entre le nom d’un contact et il récupère les informations relatives à ce contact et pas toute la table. En gros pourriez-vous me fournir une piste pour effectuer ce genre de requêtes?
    Merci d’avance et bonne continuation.

  20. boanerges (1 comments) mai 14, 2010 @ 22 h 08 min

    très bon tuto! j’ai tout réussi du premier coup!

    merci beaucoup en plus c’est super bien expliqué j’ai compris pas mal de notions 🙂

  21. DiamondToy (1 comments) mars 25, 2011 @ 17 h 21 min

    Malheureusement le tuto ne fonctionne plus. Il y a eu quelques modifications du sdk depuis sa parution, du coup certains méthodes ne renvoient plus rien.
    Serait il possible de le mettre à jour 😀 ?
    En tout cas merci quand meme 🙂

  22. kraft (36 comments) mars 29, 2011 @ 22 h 08 min

    Oui effectivement, il faut ecrire cell.textLabel.text
    au lieu de simplement cell.text

  23. vincenth (1 comments) mars 28, 2012 @ 14 h 25 min

    Good tuto !

    Ca m’intrigue !

    J’me demande comment font des applis de recherche d’annonces comme la centrale, si c’est pas tout simplement un xml qui est intéroggé à distance :o) vu qu’il me semble que c’est possible via un code comme le tient.

    En tout cas merci

  24. kraft (36 comments) mars 28, 2012 @ 15 h 32 min

    Y a des chances oui.

  25. Lilian (1 comments) avril 4, 2012 @ 11 h 00 min

    Bonjour
    Merci pour ce tuto qui fonctionne très bien, ma question serait de savoir si il était possible d’interroger plusieurs XML, je m’explique par exemple
    1.xml

    1
    Administratif – secrétariat

    2
    Informatique

    2.xml

    Avantage de l’admninistratif
    1

    en gros le id_ serait celui du 1.xml
    Cela est possible ?

  26. kraft (36 comments) avril 4, 2012 @ 20 h 36 min

    Oui bien sur.

Leave a comment