passer une valeur entre deux tabs

KRMKRM Membre
[font=verdana, geneva, lucida,]Bonjour,[/font]



[font=verdana, geneva, lucida,]J'essai désespérément de faire passer une valeur provenant du 1er onglet d'une tabbar qui scanne un QR-Code vers un 2ème onglet.[/font]



[font=verdana, geneva, lucida,]Je m'explique j'ai deux tabbar ViewControllerScan, qui permet de scanner un QR-Code et reçoit un nombre et ViewControllerData qui doit recevoir ce nombre afin de le placer dans une URL.[/font]



[font=verdana, geneva, lucida,]Il n'y a pas de bouton à  part le TabBar qui permet le lien et tout ce que je trouve pour le passage de valeur se fait toujours avec des boutons.[/font]

[font=verdana, geneva, lucida,]Voici mon storyboard: [/font]
<br />
#import &lt;UIKit/UIKit.h&gt;<br />
#import &quot;ViewControllerData.h&quot;<br />
@interface ViewControllerScan : UIViewController &lt;ZBarReaderDelegate, ViewControllerDataDelegate&gt;<br />
@property (nonatomic, retain) IBOutlet UIImageView *resultImage;<br />
@property (nonatomic, retain) IBOutlet UITextView *resultText;<br />
- (IBAction) scanButtonTapped;<br />
@end<br />




ViewControllerScan.m
<br />
#import &quot;ViewControllerScan.h&quot;<br />
@interface ViewControllerScan ()<br />
@end<br />
@implementation ViewControllerScan<br />
@synthesize resultImage, resultText;<br />
<br />
- (IBAction) scanButtonTapped<br />
{<br />
  <br />
	// ADD: present a barcode reader that scans from the camera feed<br />
	ZBarReaderViewController *reader = [ZBarReaderViewController new];<br />
	reader.readerDelegate = self;<br />
	reader.supportedOrientationsMask = ZBarOrientationMaskAll;<br />
  <br />
	ZBarImageScanner *scanner = reader.scanner;<br />
	// TODO: (optional) additional reader configuration here<br />
  <br />
  <br />
	[scanner setSymbology: ZBAR_QRCODE<br />
				   config: ZBAR_CFG_X_DENSITY<br />
					   to: 2];<br />
  <br />
	[scanner setSymbology:ZBAR_QRCODE<br />
				   config:ZBAR_CFG_Y_DENSITY<br />
					   to:2];<br />
  <br />
	reader.readerView.zoom = 1;<br />
  <br />
	reader.scanCrop= CGRectMake(0, 0, 1, 1);<br />
  <br />
	// present and release the controller<br />
	[self presentModalViewController: reader<br />
							animated: YES];<br />
  <br />
	NSLog(@&quot;je suis là &quot;);<br />
}<br />
- (void) imagePickerController: (UIImagePickerController*) reader didFinishPickingMediaWithInfo: (NSDictionary*) info<br />
{<br />
  <br />
	id &lt;NSFastEnumeration&gt; results =<br />
	[info objectForKey: ZBarReaderControllerResults];<br />
	assert(results);<br />
  <br />
	UIImage *image = [info objectForKey: UIImagePickerControllerOriginalImage];<br />
	assert(image);<br />
	if(image)<br />
		resultImage.image = image;<br />
  <br />
	ZBarSymbol *symbol = nil;<br />
	for(symbol in results){<br />
		resultText.text = symbol.data;<br />
		break;<br />
	}<br />
  <br />
	NSString* resultat = resultText.text;<br />
  <br />
	NSNumber* resultatChiffre = [NSNumber numberWithInt: 1];<br />
	NSNumber *tester = [NSNumber numberWithInt: resultat.intValue];<br />
<br />
  <br />
	NSLog(@&quot;data=%@&#092;n&quot;, symbol.data);<br />
	NSLog(@&quot;TEXTE = %@&quot;, resultText.text);<br />
  <br />
	NSLog(@&quot;ESSAI = %@&quot;, tester);<br />
  <br />
	NSLog(@&quot;TEST = %d&quot;, resultatChiffre.intValue);<br />
  <br />
	// ADD: dismiss the controller (NB dismiss from the *reader*&#33;)<br />
	[reader dismissModalViewControllerAnimated: YES];<br />
  <br />
  <br />
	ViewControllerData *controller = [[ViewControllerData alloc] initWithNibName:@&quot;ViewControllerData&quot; bundle:nil];<br />
	// Passage du nombre<br />
	[controller setMyNumber:[NSNumber numberWithInt:2]];<br />
<br />
}<br />




ViewControllerData.h
<br />
#import &lt;UIKit/UIKit.h&gt;<br />
#import &quot;RestKit/RestKit.h&quot;<br />
@class ViewControllerData;<br />
@protocol ViewControllerDataDelegate<br />
@end<br />
@interface ViewControllerData : UIViewController&lt;UIAlertViewDelegate,UITableViewDelegate, UITableViewDataSource,RKObjectLoaderDelegate&gt;<br />
{<br />
	UITableView* _tableView;<br />
	NSArray* _data;<br />
	NSString *yourString;<br />
}<br />
// Variable pour le passage du nombre (readwrite permet de faire un getter et setter automatiquement)<br />
@property (readwrite) NSNumber *myNumber;<br />
@property (nonatomic, retain) NSString *yourString;<br />
@end<br />




ViewControllerData.m
<br />
#import &quot;ViewControllerData.h&quot;<br />
#import &quot;ViewControllerDataDetail.h&quot;<br />
#import &quot;Data.h&quot;<br />
@interface ViewControllerData ()<br />
@end<br />
@implementation ViewControllerData<br />
// Nécessaire pour faire le getter et setter<br />
@synthesize myNumber;<br />
@synthesize yourString;<br />
- (void)loadTimeline {<br />
	// Charger le modèle via RestKit<br />
	RKObjectManager* objectManager = [RKObjectManager sharedManager];<br />
	objectManager.client.baseURL = [RKURL URLWithString: @&quot;http://localhost:8080/CulturalNetworksMuseumServer/resources&quot;];<br />
	[objectManager loadObjectsAtResourcePath:@&quot;/compositecards/1/artifactcards&quot; delegate:self];<br />
}<br />
- (void)viewDidLoad<br />
{<br />
	[super viewDidLoad];<br />
<br />
  <br />
	// Affichage du nombre<br />
	NSLog(@&quot;Mon nombre : %i&quot;, [myNumber intValue]);<br />
	NSLog(@&quot;Mon nombre = %@&quot;, myNumber);<br />
	NSLog(@&quot;String %@&quot;, self.yourString);<br />
  <br />
<br />
	RKLogConfigureByName(&quot;RestKit/Network*&quot;, RKLogLevelTrace);<br />
	RKLogConfigureByName(&quot;RestKit/ObjectMapping&quot;, RKLogLevelTrace);<br />
  <br />
	// Initialisation de RestKit<br />
	RKObjectManager* objectManager = [RKObjectManager managerWithBaseURLString:@&quot;http://localhost:8080/CulturalNetworksMuseumServer/resources&quot;];<br />
  <br />
	// Active la gestion automatique de l&#39;indicateur de l&#39;activité réseau<br />
	objectManager.client.requestQueue.showsNetworkActivityIndicatorWhenBusy = YES;<br />
  <br />
	//Configuration du mappage de l&#39;objet Data<br />
	RKObjectMapping * dataMapping = [RKObjectMapping mappingForClass:[Data class]];<br />
	[dataMapping mapKeyPath:@&quot;id&quot; toAttribute:@&quot;ac_id&quot;];<br />
	[dataMapping mapKeyPath:@&quot;file&quot; toAttribute:@&quot;ac_file&quot;];<br />
	[dataMapping mapKeyPath:@&quot;typefile&quot; toAttribute:@&quot;ac_typefile&quot;];<br />
	[dataMapping mapKeyPath:@&quot;author&quot; toAttribute:@&quot;ac_author&quot;];<br />
	[dataMapping mapKeyPath:@&quot;titleTopic&quot; toAttribute:@&quot;ac_titleTopic&quot;];<br />
	[dataMapping mapKeyPath:@&quot;year&quot; toAttribute:@&quot;ac_year&quot;];<br />
	[dataMapping mapKeyPath:@&quot;technical&quot; toAttribute:@&quot;ac_technical&quot;];<br />
	[dataMapping mapKeyPath:@&quot;supportMedia&quot; toAttribute:@&quot;ac_supportMedia&quot;];<br />
	[dataMapping mapKeyPath:@&quot;format&quot; toAttribute:@&quot;ac_format&quot;];<br />
	[dataMapping mapKeyPath:@&quot;owner&quot; toAttribute:@&quot;ac_owner&quot;];<br />
	[dataMapping mapKeyPath:@&quot;collection&quot; toAttribute:@&quot;ac_collection&quot;];<br />
	[dataMapping mapKeyPath:@&quot;remarks&quot; toAttribute:@&quot;ac_descritpionRemarks&quot;];<br />
  <br />
  <br />
	// Permet de mapper l&#39;objet Data avec la source de ce dernier<br />
	[objectManager.mappingProvider setObjectMapping:dataMapping forResourcePathPattern:@&quot;/compositecards/1/artifactcards&quot;];<br />
<br />
	// appel de la fonction qui charge le modèle<br />
	[self loadTimeline];<br />
}<br />




J'espère que quelqu'un peut m'aider... Je suis débutante...

Réponses

  • Voir la doc Apple à  ce sujet, c'est très clair (notamment la partie intitulée Configuring the Destination Controller When a Segue is Triggered)"
  • Bonjour KRM,



    À la fin de imagePickerController: dans ViewControllerScan.m, tu fais une nouvelle instance de ViewControllerData et tu lui passes un nombre. Mais tu ne fais plus rien de ce contrôleur, il disparaà®t donc. Ce n'est pas lui qui est affiché quand on appuie sur le bouton de navigation du tab.



    Je suis aussi débutant donc je ne sais pas quelle est la meilleure façon de faire mais il est clair qu'il faut soit:

    - Ajouter une transition (Segue) vers la tab "data" et la déclencher dans ViewControllerScan.m par du code en y passant la valeur à  ce moment.

    - Stocker la donnée à  passer dans un objet qui reste en vie plus longtemps que tes deux contrôleurs, au pire un singleton (mauvaise pratique pour cet exemple mais l'idée est de donner la valeur à  un objet qui dans la logique de ton application est vivant pendant toute l'existence de ces deux tabs).
  • KRMKRM Membre
    donc il faudrait que je mette ce code dans ViewControllerScan.m
    <br />
    - (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender<br />
    	    ViewControllerData *viewControllerData = [segue destinationViewController];<br />
    data.myNumber = 2;<br />
    <br />
    }<br />
    
    ?



    Parce que mon Storyboard Segues n'a pas de nom vu que la relation est un Relationship



    C'est juste?
  • 'KRM' a écrit:


    donc il faudrait que je mette ce code dans ViewControllerScan.m
    <br />
    - (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender<br />
    		ViewControllerData *viewControllerData = [segue destinationViewController];<br />
    data.myNumber = 2;<br />
    <br />
    }<br />
    
    ?



    Parce que mon Storyboard Segues n'a pas de nom vu que la relation est un Relationship



    C'est juste?




    Ah oui effectivement, j'avais mal vu ton storyboard. Le prepareForSegue ne sera jamais appelé. Tu devrais peut-être stocker de façon persistante ta valeur de telle sorte qu'elle soit facilement accessible par n'importe quel controller (je rejoins l'avis de Noliv) : si l'utilisateur veut fermer ton appli, tu auras peut-être besoin de récupérer ta donnée.
  • nolivnoliv Membre
    août 2012 modifié #6
    Je viens de faire un petit test pour voir si j'arrivais à  faire un Segue comme je l'avais vu dans une vidéo de la WWDC, de mémoire, sans regarder à  nouveau la vidéo... hé bin non! image/biggrin.png' class='bbc_emoticon' alt=':D' />



    Le truc un peu spécial, c'est que tu fonctionnes avec des tabs... et je ne sais pas exactement la meilleure façon de procéder.



    Cependant, le plus simple me semble maintenant d'utiliser (à  la fin de ton action, quand tu as le résultat du scan) la propriété
    [self.tabBarController.viewControllers objectAtIndex:1]
    
    pour obtenir ton deuxième tab, lui passer la valeur que tu veux, et enfin le code suivant pour activer le deuxième tab à  l'écran:
    self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:1];<br />
    
  • KRMKRM Membre
    <br />
    [self.tabBarController.viewControllers objectAtIndex:1];<br />
        ViewControllerData *controller = [[ViewControllerData alloc] initWithNibName:@&quot;ViewControllerData&quot; bundle:nil];<br />
        // Passage du nombre<br />
        [controller setMyNumber:[NSNumber numberWithInt:2]];<br />
        self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:1];<br />
    




    Le passage de la valeur est juste? car j'ai essayé ton code, malheureusement "myNumber" = 0 alors que mon scan vaut 1...

    Merci beaucoup de vous creusé la tête avec moi...
  • KRMKRM Membre
    et sinon pour stocker de façon persistante, il faut que je crée une classe de type NSObject s'appelant par exemple QRCode et comme variable il y aurait un int ou NSString ou autre.

    Puis depuis Scan je fait un set et depuis Data un get.

    Ou bien?
  • nolivnoliv Membre
    août 2012 modifié #9
    Non essaie plutôt ceci :


    // On va chercher le contrôleur du tab 2 dans le tabBarController :<br />
    ViewControllerData *controller = [self.tabBarController.viewControllers objectAtIndex:1];<br />
    <br />
    // Pour bien faire, il faudrait vérifier si on a vraiment obtenu un résultat,<br />
    // et assigner un nouveau contrôleur tout neuf si ce n&#39;est pas le cas...<br />
    // [[ViewControllerData alloc] initWithNibName:@&quot;ViewControllerData&quot; bundle:nil];<br />
    // à  la limite, vérifie que l&#39;objet n&#39;est pas nul avec un log :<br />
    NSLog(@&quot;Mon objet qui ne doit pas être nul : %@&quot;, controller);<br />
    <br />
    // Passage du nombre<br />
    [controller setMyNumber:[NSNumber numberWithInt:2]];<br />
    self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:1];<br />
    




    Ta question sur le stockage de façon persistante m'embête un peu parce qu'on dirait qu'il faut revoir les bases de la programmation orientée objet... c'est vaste, les bouquins le font mieux que moi, et ça dépasse un peu le temps que je souhaite consacrer aux forum(s?)... image/wink.png' class='bbc_emoticon' alt=';)' />
  • KRMKRM Membre
    merci mille fois ça à  fonctionner... je vais tout de suite tester avec mon URL... merci merci merci. trop beau ça fait des jours que je suis là  dessus sans succès.
  • KRMKRM Membre
    une dernière question et j'arrête...

    pour le placer à  la place du 1 dans l'url qui suit:


    <br />
    [objectManager.mappingProvider setObjectMapping:dataMapping forResourcePathPattern:@&quot;/compositecards/1/artifactcards&quot;<br />
    


    j'ai essayé de faire :
    <br />
    [objectManager.mappingProvider setObjectMapping:dataMapping forResourcePathPattern:@&quot;/compositecards/%@/artifactcards&quot;, myNumber<br />
    


    mais il ne prend qu'un argument. un conseil?
  • AstramAstram Membre
    août 2012 modifié #12
  • KRMKRM Membre
    certe mais le problème et qu'il ne demande qu'un argument alors il n'apprécie pas ", myNumber"...
  • oui mais tu formate une chaine là , alors que ce n'est pas ça qui est attendu
  • AliGatorAliGator Membre, Modérateur
    août 2012 modifié #16
    Je ne connais pas RestKit, je ne l'ai jamais utilisé.

    Pourtant en voyant ce sujet, j'ai lancé Google, j'ai recherché la méthode "setObjectMapping:forResourcePathPattern:" et suis donc tombé en 2s sur sa documentation. Et je lis donc dan la doc de cette méthode :
    The resourcePathPattern is a SOCKit pattern matching property names preceded by colons within a path. For example, if a collection of reviews for a product were loaded from a remote system at the resourcePath @“/products/1234/reviews”, object mapping could be configured to handle this request with a resourcePathPattern of @“/products/:productID/reviews”.




    Donc ça me semble clair, ce n'est pas un "%d" ou "%@ qu'il faut mettre, ce n'est pas une chaà®ne à  la stringWithFormat" qu'il faut utiliser avec des placeholders pour le formattage, ce sont des "property names preceded by colons" comme le ":productID" de l'exemple donné par la doc.



    Après, comment utiliser tout ça, bah ça doit aussi être expliqué dans la doc hein. J'ai mis 2s à  trouver cette information donc je vous laisse trouver pour le reste comment faire ce mapping. Mais bon il me semble vu le nom des classes et des méthodes que l'objet RKObjectMappingProvider... est justement là  pour ça, c'est justement son rôle de créer des mappings / correspondances entre un objet (avec ses propriétés) et la requête REST équivalente à  envoyer pour récupérer les infos de cet objet...
  • AstramAstram Membre
    août 2012 modifié #17
    jamais utilisé non plus, et pas cherché image/smile.png' class='bbc_emoticon' alt=':)' />
  • KRMKRM Membre
    merci je vais essayer cela...
  • KRMKRM Membre
    merci à  tous....

    voici la réponse:
    <br />
    NSString *stringURL = [NSString stringWithFormat:@&quot;/compositecards/%d/artifactcards&quot;, myNumber.intValue];<br />
        [objectManager.mappingProvider setObjectMapping:dataMapping forResourcePathPattern:stringURL];<br />
    
  • AliGatorAliGator Membre, Modérateur
    (*soupir*)

    A se demander à  quoi ça te sert d'utiliser un MappingProdiver si tu fais le mapping en dur toi-même...
Connectez-vous ou Inscrivez-vous pour répondre.