# Question pour un Navigation Based App avec Core Data



## Mkdisco (27 Septembre 2010)

Bonsoir,

Débutant sur XCode, j'ai eu l'excellente idée de me lancer sur un premier projet d'application iPhone "navigation based" avec Core Data. Et pour déguster, je déguste 

Je vais utiliser un exemple pour poser ma question :

Admettons que j'ai trois entités différentes "voiture" "vélo" et "bateau", chacunes avec leurs attributs respectifs. Je voudrais dans une tableview afficher ma liste de voitures en section 1, de vélos en 2, de bateaux en 3...

De plus, je souhaiterais que la sélection d'une cellule renvoie vers des vues détaillées propres à chaque section (puisque mes voitures, vélos et bateaux n'ont pas les mêmes attributs à détailler...).

Est-ce possible ?

Le cas échéant auriez-vous quelques pistes ou références ? Car pour l'instant, dans tutos, livres et docs divers (...) il ne me semble pas avoir croiser ce type de cas de figure.

Si c'est impossible, j'ai un plan B mais qui me plait moins...

Merci de votre attention et désolé si j'ai écrit des hérésies XCodiennes. Mais je débute et il est tard...


----------



## Nyx0uf (27 Septembre 2010)

http://developer.apple.com/library/...ultsController_Class/Reference/Reference.html


----------



## BooBoo (27 Septembre 2010)

Je ne suis pas sur que de commencer directement avec Core Data soit la bonne methode...
Pour une appli toute simple, genre tout les tutos que l'on trouve dans les bouquins et le web, ca va aller.
Mais pour faire quelque chose de concret, il faut comprendre un peu ce qui se cache derrière...
(mais c'est juste mon avis...)


----------



## Lio70 (28 Septembre 2010)

Core Data c'est pour les touristes. On te promene partout en minibus, tu observes un maximum, tu prends des photos. Mais tu ne te meles pas a la population locale, tu ne la connais donc pas et tu crois que ce n'est pas utile sous pretexte que tu ne passeras jamais plus de deux semaines de vacances a la fois dans cet endroit.

Erreur! Pour comprendre la mecanique de ton application, tu dois mettre les mains dans le cambouis. Comprendre les rouages du bidule. Ensuite, tu passes a Core Data pour simplifier certaines taches.


----------



## ntx (28 Septembre 2010)

Mkdisco a dit:


> Admettons que j'ai trois entités différentes "voiture" "vélo" et "bateau", chacunes avec leurs attributs respectifs. Je voudrais dans une tableview afficher ma liste de voitures en section 1, de vélos en 2, de bateaux en 3...
> 
> De plus, je souhaiterais que la sélection d'une cellule renvoie vers des vues détaillées propres à chaque section (puisque mes voitures, vélos et bateaux n'ont pas les mêmes attributs à détailler...).
> 
> ...


Tu  n'as pas du fouiller bien longtemps avant de venir poser ta question :rateau: C'est quand même un peu l'exemple de base dans le doc d'Apple


----------



## tatouille (29 Septembre 2010)

"Et pour déguster, je déguste" il y a que les cons qui ne savourent pas une bonne anale.


----------



## Mkdisco (30 Septembre 2010)

D'abord merci pour vos réponses !

Ensuite, c'est à croire que l'anal en séances intensives et sans beurre stimule le cerveau puisque j'ai progressé jusqu'à résoudre la première partie de ma question.

Pour afficher tous mes trucs dans une même tableView, il suffisait d'élargir mon modèle à une entité générale "machine" ayant par exemple un attribut "type" commun, celui-ci ayant une valeur "vélo", "voiture" ou "bateau" servant de critère au fetchedResultsController pour former les sections de la table. Oh Yeah !

Par contre j'ai un gros problème pour la suite, à savoir renvoyer vers des vues détaillées différentes selon la section de la cellule sélectionnée.

Dans 
	
	



```
tableView didSelectRowAtIndexPath
```
 j'ai d'abord fait ceci :


```
switch ([indexPath section]) {
		case 0:
			
			VeloViewController *aViewController = [[VeloViewController alloc] initWithNibName:@"VeloViewController" bundle:nil];
			break;
		case 1:	
(...)
}

		Machine *machine = (Machine *)[[self fetchedResultsController] objectAtIndexPath:indexPath];
		aViewController.machine = machine;
		[self.navigationController pushViewController:aViewController animated:YES];
		[aViewController release];
```

Et là, devant les déclarations "VeloViewController *aViewController" j'ai l'erreur : "Expected expression before VeloViewController"

J'ai essayé une autre manière en me basant sur des samples de code :


```
UIViewController *aViewController = nil;
	
	switch ([indexPath section]) {
		case 0:
			
			aViewController = [[VeloViewController alloc] initWithNibName:@"VeloViewController" bundle:nil];
			break;
			
(...)
	}
	
	if (aViewController) {
		Machine *machine = (Machine *)[[self fetchedResultsController] objectAtIndexPath:indexPath];
		aViewController.machine = machine;
		[self.navigationController pushViewController:aViewController animated:YES];
		[aViewController release];
	}
```

J'ai alors "Request for member machine in something not a structure or union" devant "aViewController.machine = machine."

Vous n'auriez pas un tuyau par hasard ?

Ou alors dites-moi juste si ce que je veux faire est possible. Merci & bonne journée


----------



## Nyx0uf (30 Septembre 2010)

Pour le premier cas :

Tu ne peux pas instancier dans un case, ou alors faut mettre des braces autour, ou déclarer ta var au dessus du switch :


```
VeloViewController *aViewController = nil;
switch ([indexPath section]) {
		case 0:
			
		        aViewController = [[VeloViewController alloc] initWithNibName:@"VeloViewController" bundle:nil];
			break;
		case 1:	
(...)
}
```




Pour le 2ème cas :

Normal, aViewController est de type UIViewController, et aux dernières nouvelles y pas de propriétés machine dans cette classe, donc faut caster.


```
((VeloViewController*)aViewController).machine = machine;
```

Mais c'est vraiment moyen.


----------



## Mkdisco (30 Septembre 2010)

Merci de ta réponse.

Franchement, je n'ai pas tout compris, j'ai beaucoup de problèmes de traduction.
J'ai quand même compris quand tu dis qu'on ne peut instancier dans un "case"... Ce qui m'a poussé à cette solution, où je crée tout "dehors" (trois contrôleurs de vue alors que je n'en ai besoin que d'un... lol) et mets seulement le lancement de la nouvelle vue dedans...


```
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
	
	Machine *selectedMachine = (Machine *)[[self fetchedResultsController] objectAtIndexPath:indexPath];

	VeloViewController *veloViewController = [[VeloViewController alloc] initWithNibName:@"VeloViewController" bundle:nil];
	BateauViewController *bateauViewController = [[BateauViewController alloc] initWithNibName:@"BateauViewController" bundle:nil];
	VoitureViewController *voitureViewController = [[VoitureViewController alloc] initWithNibName:@"VoitureViewController" bundle:nil];
	
	switch ([indexPath section]) {
		case 0:
			veloViewController.machine = selectedMachine;
			[self.navigationController pushViewController:veloViewController animated:YES];
			break;
		case 1:
			bateauViewController.machine = selectedMachine;
			[self.navigationController pushViewController:bateauViewController animated:YES];
			break;
		case 2:
			voitureViewController.machine = selectedMachine;
			[self.navigationController pushViewController:voitureViewController animated:YES];
			break;
	}
	
	[veloViewController release];
	[bateauViewController release];
	[voitureViewController release];
}
```

J'ai honte tellement c'est bourrin et inélégant. Mais ça marche, ce qui est déjà quelque chose d'appréciable !!!


----------



## Nyx0uf (30 Septembre 2010)

Tous tes controlleurs ont un point commun, une ivar machine.

Crées une base class abstraite avec l'attribut machine et dans VeloViewController, BateauViewController et VoitureViewController tu hérites de cette classe.


----------



## BooBoo (30 Septembre 2010)

```
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
	
	Machine *selectedMachine = (Machine *)[[self fetchedResultsController] objectAtIndexPath:indexPath];

	MyViewController *myViewController ;
	
	switch ([indexPath section]) {
		case 0:
      			myViewController =    [[VeloViewController alloc] initWithNibName:@"VeloViewController" bundle:nil];               
			break;
		case 1:
      			myViewController = [[BateauViewController alloc] initWithNibName:@"BateauViewController" bundle:nil];
			break;
		case 2:
      			myViewController = [[VoitureViewController alloc] initWithNibName:@"BateauViewController" bundle:nil];
			break;
	}
	myViewController .machine = selectedMachine;
	[self.navigationController pushViewController:myViewController animated:YES];
	[myViewController release];
}
```


----------



## tatouille (1 Octobre 2010)

un simple controller construteur prenant un type, sur le initialize tu load le nid contenant trois vues superposees ...


----------



## BooBoo (1 Octobre 2010)

tatouille a dit:


> un simple controller construteur prenant un type, sur le initialize tu load le nid contenant trois vues superposees ...



Tantouille, tu es souvent (toujours ?) de bon conseil... mais tu ne te mets pas au niveau des nioub pour qu'ils te comprennent (ne te vexe pas comme un nioub).
Personellement, j'y arrive un peu (je ne suis plus un nioub ?) même si je sais que ce que je fais  (propose) n'est pas idéalement structuré et séparé avec les design pattern et le MVC


----------



## tatouille (1 Octobre 2010)

mouarf  c'est surtout pour les performances plus que pour le MVC (surtout dans le callback d'une tableview qui va etre appeler a chaque repaint) ouvrir et parser des nibs (bien sur ils sont gardes en memoire) mais bon sur iphone il vaut mieux eviter un ou deux nibs sont suffisants utilisant les supperpositions et tu hide show ou deplaces les vues, dans ton nib elles peuvent etre or champs le tout c'est de connaitre leurs coordonnées de depard, il vaut mieux mettre en memoire au depard.

Boo prend un chewing gum ca ira mieux apres  parce qu'il semblerait que tu te sois vexé la


----------



## BooBoo (2 Octobre 2010)

Je ne suis pas du tout vexé.
Je pensais que ton message ne me répondait pas mais je viens juste de voir le titre de ton post !

Mais je crois que tu fais exprès de te mettre a un niveau au dessus de la personne a qui tu réponds.

Je vais en rester là car je lis toujours tes post avec intérêt, glanant toujours qq nouvelles connaissances (malheureusement l'inverse n'est pas vrai).

PS: c'est quoi le rapport avec le message en lien ?


----------

