[Objective-c + JSON-RPC] Discuter avec un serveur

Bonjour,



voila je suis tout nouveau je viens tout juste de m'inscrire sur ce forum. Je suis étudiant et je viens tout juste de me lancer le langage Objecive-c et dans la programmation d'aplication mobile pour Iphone ou j'essaie d'utiliser xCode 4.

Et du coup j'ai un petit problème à  vous soumettre, vous comprendrez aussi que je suis tout nouveau, donc soyez un peu indulgent avec moi image/smile.png' class='bbc_emoticon' alt=':)' />



Voila, je souhaite poourvoir discuter avec un serveur en utilisant du Json-Rpc, en gros pour le moment, je veux juste me logué dessus recevoir le cookie de session et le token.

Donc dans votre grande générosité serait il possible que quelqu'un me renseigne sur les étapes à  faire et si une librairie est nécéssaire ou pas, à  part le framework de base sur mon xCode je connais rien d'autre. (et vous comprendrez aussi que mon niveau d'anglais est ....)

Avec si possible un ptit exemple, svp ?
Mots clés:
«1

Réponses

  • AliGatorAliGator Membre, Modérateur
    Une librairie est nécessaire, tu peux utiliser la mienne (cf dans ma signature) : JSONRPCFramework

    Ca fait un bail que je l'utilise pour ma propre appli, et ça marche très bien.
  • Merci pour ton post.

    Je suis allé voir ton framework et après avoir parcouru tes classes, je suis allé voir ton projet_exemple, et à  vrais dire, je n'y ai pas compris grand chose (désolé je débute).

    Si possible peux-tu implémenter ton framework avec un prit exemple, style une fonction pour se loguer sur un serveur avec un user et un password et qui me retourne le cookie de connection ?

    Cela m'aiderais beaucoup à  avancer.

    Merci d'avance
  • Commence par essayer de comprendre l'exemple fourni en modifiant des parties et en observant le résultat. Tu finira par comprendre le fonctionnement qui n'est pas très complexe dans l'absolu.
  • AliGatorAliGator Membre, Modérateur
    Le problème c'est que ce que tu demandes comme exemple est impossible : ça dépend de ton serveur.



    Mon framework permet d'échanger avec n'importe quel serveur qui communique en JSON-RPC. Il permet d'envoyer n'importe quel message en JSON-RPC quand tu lui fournis le nom de la méthode à  appeler et les paramètres à  passer à  ladite méthode.



    Mais après, chaque serveur propose ses propres méthodes de WebService. Ton serveur peut avoir une méthode de WebService pour retourner une liste d'utilisateurs, ou une méthode de WebService pour te retourner la météo d'une ville donnée... ou une méthode de WebService pour "se loguer avec un login/pass et qu'il te retourne un cookie de connexion". Un autre serveur proposera d'autres méthodes, avec d'autres paramètres, ... ça dépend de ton serveur, je ne sais pas quelles méthodes il expose, quelles sont les noms des méthodes qu'il propose et les paramètres qu'il attend pour ces méthodes, je peux pas le deviner.



    C'est un peu comme si je tu avais un parseur XML et que tu me demandais comment parser un XML de liste de livres que tu as récupéré. Je ne sais pas quelle est la structure de ton XML, je ne peux pas le deviner, donc je ne peux pas trop te donner d'exemple, le parseur XML en question étant générique à  toi d'indiquer les tags dont tu veux lire le contenu, etc.

    bah avec mon framework JSON-RPC c'est pareil, ça permet de communiquer avec un serveur qui respecte le protocole JSON-RPC, après pour appeler une méthode de ton WebService avec mon framework bah encore faut-il connaà®tre le nom de la méthode à  appeler et ses paramètres.
  • Désolé, c'est vrai que sans les méthodes un exemple serait un peu compliqué. image/tongue.png' class='bbc_emoticon' alt=':P' />

    Ma méthode pour se logé est la suivante:





    {"login":{"envelope":"JSON-RPC-2.0","transport":"POST","parameters":[{"type":"string","name":"s_login","optional":false},{"type":"string","name":"s_password","optional":false},{"type":"boolean","name":"b_remember_me","optional":true,"default":false}],"returns":["null","null"]}

    Donc il faut du JSON-RPC version 2.0 et POST en transport, pour les paramètres obligatoire, il faut le login et le passeword,le reste est optionnel et est censé me retourné rien du tout, sinon une erreur. Pour se connecter sur mon serveur, http://IP/auth



    Voila, je sais pas si tu peux me faire un ptit exemple avec cette méthode, histoire de mieux appréhender la suite. Je t'en serais reconnaissant.
  • AliGatorAliGator Membre, Modérateur
    Ok, et qu'est ce que tu ne comprends pas dans ma documentation sur le sujet ?

    (cf la doc Doxygen fournie avec le projet, ou même les petites pages de démarrage rapide dans la partie Wiki de mon GitHub, en particulier celle-là ) ? Pourtant je pensais avoir fait une doc assez riche ?
  • J'ai consulté tes liens, donc si je comprend bien, si je veux appeler cette méthode, je dois tout naturellement d'abord inclure ton framework dans mon projet (glisser-déposer "AliJSONRPC Framework" -> Mon projet). Ensuite:



    Je dois créer une instance de service, en fournissant l'URL et la version JSON-RPC de mon WebService :



    JSONRPCService * service = [JSONRPCService serviceWithURL:"http//IP/auth version:JSONRPCVERSION_2.0];



    Et après appelez la méthode de la manière suivante:



    [service callMethodWithName:@login parameters:mkArray(@s_login,@s_password)]



    Voila, dit moi si je suis sur la bonne voie image/huh.gif' class='bbc_emoticon' alt='???' />

    Et sinon comment faire pour envoyer également un identifiant à  ma méthode, non pas en paramètre de ma méthode, mais un identifiant à  ma méthode, (Je ne sais pas si je me suis fait comprendre :/ )
  • AliGatorAliGator Membre, Modérateur
    Oui c'est bien comme ça qu'il faut faire, tout à  fait !



    Après une fois que la méthode est appellée, tu peux récupérer le résultat de plusieurs manières :

    - soit tu implementes les méthodes de delegate pour recevoir toutes les réponses, quitte à  filtrer ensuite en utilisant le paramtres JSONRPCMethodCall qui est passé en delegate et qui indique à  quelle méthode et quels paramètres correspond cette réponse

    - soit tu utilises le fait que callMethodWithName te retourne un objet JSONRPCResponseHandler, solution que je te conseille. Le principe de cet objet retourné c'est juste de permettre d'indiquer comment va être manipulée/traitée la réponse.



    Quand tu récupères un objet JSONRPCResponseHandler, tu peux :

    - lui indiquer le delegate et la callback à  appeler (un peu sur le même principe que le mécanisme target/action, tu indiques un objet delegate et la méthode/le @selector à  appeler quand la réponse est disponible)

    - ou plutôt lui indiquer un completionBlock (perso j'adore les blocks, une fois qu'on y est habitué c'est royal ça fait du code propre à  lire et sympa, mais si tu n'es pas familier encore avec les blocks je comprend que ça puisse te dérouter), c'est à  dire lui indiquer un bloc de code à  exécuter quand la réponse sera disponible

    - tu peux aussi faire d'autres petits trucs sympas avec ce ResponseHandler, comme par exemple demander à  ce que la réponse JSON soit automatiquement convertie en un objet Cocoa de ton modèle plutôt que de récupérer un NSArray ou un NSDictionary... mais bon n'allons pas trop vite.



    Du coup le principe pour traiter la réponse, c'est soit tout ton JSONRPCService a un delegate et reçoit toutes les réponses (pas très pratique, mais faisable), soit en retour de l'appel à  callMethodWithName:parameters: (ou toute méthode similaire), indiquer à  l'objet ResponseHandler retourné comment traiter la réponse :
    // première possibilité :<br />
    JSONRPCResponseHandler* rh = [service callMethodWithName:@&quot;login&quot; parameters:mkArray(@&quot;s_login&quot;,@&quot;s_password&quot;)];<br />
    [rh setDelegate:self callback:@selector(loginMethod:didLogin:error:)];<br />
    // puis implémenter -(void)loginMethod:(JSONRPCMethodCall*)mc didLogin:(id)result error:(NSError*)error; pour traiter la réponse<br />
    <br />
    // Note que tu peux enchaà®ner les 2 appels pour rendre ça plus compact évidemment :<br />
    [[service callMethodWithName:@&quot;login&quot; parameters:mkArray(@&quot;s_login&quot;,@&quot;s_password&quot;)]<br />
        setDelegate:self callback:@selector(loginMethod:didLogin:error:)];<br />
    <br />
    // Autre méthode, la syntaxe avec les blocks :<br />
    <br />
    [[service callMethodWithName:@&quot;login&quot; parameters:mkArray(@&quot;s_login&quot;,@&quot;s_password&quot;)]<br />
        completion:^(JSONRPCMethodCall* methodCall,id result,NSError* error)<br />
    {<br />
       NSLog(@&quot;La méthode de login %@ vient de répondre. Le résultat est : %@, l&#39;erreur est : %@&quot;, methodCall,  result, error);<br />
    }];<br />
    
  • OKy, merci pour toutes tes précisions, cela me permet d'avancer assez rapidement image/smile.png' class='bbc_emoticon' alt=':)' />



    Par contre du coup, il me reste toujours ce petit problème, voila comme je veux que ma méthode soit identifié ( int id ), je ne sais pas du coup ou le fournir, est ce dans l'instance de service ou dans la méthode a appelé ou ailleurs??



    Sinon question un peu con, tu me diras, est ce que pour implémenter ton framework, est ce que vraiment un simple glisser-déposer du dossier dans mon dossier de projet suffis, ou d'autre manipulation sont nécessaire ?



    Sinon merci encore pour toute tes précisions image/smile.png' class='bbc_emoticon' alt=':)' />
  • image/huh.gif' class='bbc_emoticon' alt='???' />?? Ptit soucis avec ton framework, quand j'appuis sur Run il me me détecte plein d'erreur dans tes fichiers !!!

    Est ce moi qui est mal fait ?
  • AliGatorAliGator Membre, Modérateur
    Oui le plus simple est de glisser-déposer le dossier dans ton projet.



    Sinon pour identifier ta méthode je ne comprend pas trop ce que tu veux faire, et l'utilité que tu en aurais... tu voudrais mettre une sorte de tag sur les appels de méthodes que tu envoies, pour pouvoir le comparer à  la réception de la requête par exemple ?



    En même temps, si tu utilises les méthodes que je t'ai indiquées pour récupérer la réponse à  chaque appel de méthode, en as-tu vraiment besoin ?



    Ceci dit, sache qu'en interne chaque appel de méthode JSON-RPC est composée, d'après la spécification JSON-RPC, d'un nom de méthode, d'une liste de paramètres... et d'un "UUID" (identifieur unique). Or tu peux accéder à  ce UUID via la propriété uuid de l'objet JSONRPCMethodCall. C'est sans doute avec cela que tu vas pouvoir t'en sortir si tu veux un identifiant unique par appel de méthode.



    - Si tu crées toi-même un JSONRPCMethodCall (pour lui indiquer le nom de la méthode et les paramètres, et le passer ensuite à  la méthode callMethod) tu peux donc directement accéder au uuid généré pour ce JSONRPCMethodCall.

    - Si tu appelles la méthode de commodité "callMethodWithName:parameters" qui construit le JSONRPCMethodCall pour toi, elle te retourne un objet JSONRPCResponseHandler comme je t'ai déjà  expliqué, et cet objet contient une propriété te permettant d'accéder au JSONRPCMethodCall, et donc de là  de récupérer le uuid utilisé.
  • AliGatorAliGator Membre, Modérateur
    'yass_1988' a écrit:


    image/huh.gif' class='bbc_emoticon' alt='???' />?? Ptit soucis avec ton framework, quand j'appuis sur Run il me me détecte plein d'erreur dans tes fichiers !!!

    Est ce moi qui est mal fait ?
    Mon framework n'est pas compatible ARC.

    Si tu utilises ARC dans ton projet (et donc que tu vas avoir plein de messages concernant les appels à  retain/release), il faut que tu désactives ARC pour les fichiers de mon framework (Rajouter le flag "-fno-objc-arc" pour les fichiers de mon framework, dans l'onglet "Build Phases" des réglages du projet sous Xcode4, colonne "Compiler Flags" de la section "Compile Sources")
  • Heuuu, excuse moi Ali, je commence tout juste à  prendre en main Xcode, veux tu me réexplique les cheminements ? Ou se trouve la section Compile Sources ?
  • Oky c'est bon , j'ai rajouter tout les flags à  tes fichiers de framework, par contre quand je Run, bien il continu à  me marquer des erreurs, njustement des messages concernant les appels à  release
  • Sinon j'en profite pour te montrer mon programme principal, tu me diras du coup s'il est bon, en attendant de régler les petits soucis:





    //


    // main.m


    // test_connection


    //


    // Created by Yassine Badih on 05/04/12.


    // Copyright (c) 2012 __MyCompanyName__. All rights reserved.


    //




    #import <UIKit/UIKit.h>




    #import "AppDelegate.h"




    #import "JSONRPCService.h"




    #import "JSONRPCMethodCall.h"




    #import "JSONRPCResponseHandler.h"




    int main(int argc, char *argv[])

    {



    NSURL * serviceURL = /color][color=#7134aa]NSURL[/color][color=#000000] [/color][color=#401082]URLWithString[/color][color=#000000]:[/color]@&quot;http://***.***.***.***/auth/rpc.php&quot;[color=#000000;




    JSONRPCService * service = /color][color=#578187]JSONRPCService[/color][color=#000000] [/color]serviceWithURL[color=#000000]:serviceURL [/color]version[color=#000000]:[/color]JSONRPCVersion_2_0[color=#000000;


    NSLog(@blabla);




    [[service callMethodWithNameAndParams:@login,@admin,@123456, nil]


    completion:^(JSONRPCMethodCall * methodCall,id result,NSError * error)

    {

    NSLog(@La méthode de login %@ vient de répondre. Le résultat est : %@, l'erreur est : %@", methodCall, result, error);


    }];



    NSLog(@blabla);


    @autoreleasepool {


    return UIApplicationMain(argc, argv, nil, NSStringFromClass(/color][color=#578187]AppDelegate[/color][color=#000000] [/color]class[color=#000000));


    }

    }
  • Ha c'est bon, je crois que sa marche, voila le résultat, sur la console:





    objc[949]: Object 0x6878e10 of class NSURL autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug

    objc[949]: Object 0x6879160 of class JSONRPCService autoreleased with no pool in place - just leaking - break on objc_autoreleaseNoPool() to debug

    2012-04-05 11:06:02.736 test_connection[949:f803] blabla

    2012-04-05 11:06:02.758 test_connection[949:f803] blabla

    2012-04-05 11:06:03.249 test_connection[949:f803] La méthode de login <JSONRPCMethodCall login(admin,123456)> vent de répondre. Le résultat est : (null), l'erreur est : (null)



    Par contre normalement, qu'on je suis censé me logé avec la méthode login, elle est censé me renvoyé nulle en résultat (Visiblement c'est bon), mais je dois aussi recevoir un cookie de session
  • AliGatorAliGator Membre, Modérateur
    avril 2012 modifié #19
    Alors ton code est bon... mais si tu le mets dans le "main.m" et surtout à  l'extérieur de toute @autoreleasepool, c'est normal que tu reçoives des message au runtime sur des messages autorelease qui n'ont aucune autoreleasepool dans laquelle aller ! (tu dois avoir des messages genre "Object xxx autoreleased with no pool in place" du coup puisque tu exécutes ton code en dehors de toute autoreleasepool)

    Du coup ça n'a rien à  voir avec mon framework (tu mettrais du code à  toi là  dedans au aurais aussi ce genre d'erreur)



    En général dans un programme Cocoa, on ne touche jamais au main.m. On laisse le main.m créer une autoreleasepool et appeler UIApplicationMain, comme c'est fait par défaut, qui va s'occuper de tout plein de trucs nécessaires (préparer une RunLoop, charger ton interface principale, initialiser les classes donc la UIApplication et son delegate, etc).



    Du coup, en Cocoa, si tu veux exécuter du code au lancement de ton application, ne ne faut pas les placer dans le main, mais laisser le UIApplicationMain faire son boulot, et mettre le code dans le delegate de ta UIApplication (dans AppDelegate.m donc), dans la méthode "applicationDidFinishLaunchingWithOptions:" qui elle est appelée quand l'initialisation est finie et ton programme est prêt.
  • D'accord, ok, mais pour le moment c'est seulement pour tester, du coup j'ai tout mis dans mon @autoreleasepool, et j'ai plus de message au runtime, par contre je m'attendais du coup en plus d'avoir la réponse à  ma méthode, je croyais que j'aurais aussi la réponse du header ou dedans je pourrais le cookie de session.



    C'est possible ? Comment ?
  • En faite l'idée de mon application et que au démarrage on puisse se logé sur un serveur pour récupérer le cookie et ensuite via le cookie récupérer le token, car c'est avec lui après que je travaillerais exclusivement pour m'identifier auprès du serveur et appeler d'autre méthode.
  • AliGatorAliGator Membre, Modérateur
    Je ne crois pas avoir prévu de pouvoir accéder aux headers de la réponse HTTP, vu que normalement les WebServices JSON-RPC ne communiquent toutes les infos que par la réponse JSON retournée (cf la spécification JSON-RPC), et pas par les headers.

    (Le WebService que tu attaques n'est donc pas forcément conforme à  100% à  la spec donc, mais bon, passons)



    Par contre normalement les cookies sont gérés automatiquement par le WebKit, tu ne devrais donc pas avoir à  t'en soucier. Quand tu reçois des cookies dans les headers de la réponse d'une requête, le WebKit les enregistre dans le HTTPCookieStorage pour les garder de côté naturellement.

    Tu devrais donc pouvoir récupérer les cookies directement via [[[font=Courier, Consolas, monospace]NSHTTPCookieStorage [/font][font=Courier, Consolas, monospace]sharedHTTPCookieStorage] [/font][font=Courier, Consolas, monospace]cookiesForURL:service.serviceURL][/font] pour aller lire tous les cookies associés à  ton service.
  • Merci bop Ali, du coup j'arrive à  récupérer le cookie que je veux, je vais pouvoir du coup avancer.

    Merci pour tes conseils et ton framework (Bien pratique comparé à  DefferedKit et surtout plus facile à  prendre en main).

    j'espère que vous serez tirs à  l'écoute si d'autre soucis se présenter image/smile.png' class='bbc_emoticon' alt=':)' />
  • Désolé, je relance la discussion, j'ai rencontré un nouveau soucis:







    Dossier ViewController.m:



    #import "ViewController.h"




    #import "JSONRPC.h"




    #import "JSONRPC_Extensions.h"




    #import "JSONRPCService.h"




    #import "JSONRPCMethodCall.h"




    #import "JSONRPCResponseHandler.h"






    @interface ViewController ()




    @end




    @implementation ViewController



    - (void)viewDidLoad

    {

    /color][color=#b41ca4]super[/color][color=#000000] [/color]viewDidLoad[color=#000000;


    NSURL * serviceURL = /color][color=#7134aa]NSURL[/color][color=#000000] [/color][color=#401082]URLWithString[/color][color=#000000]:[/color]@&quot;http://***.***.***.***/auth/rpc.php&quot;[color=#000000;


    JSONRPCService * service = /color][color=#578187]JSONRPCService[/color][color=#000000] [/color]serviceWithURL[color=#000000]:serviceURL [/color]version[color=#000000]:[/color]JSONRPCVersion_2_0[color=#000000;


    service [color=#38595d]callMethodWithNameAndParams[/color]:[color=#c72c25]@&quot;login&quot;[/color], [color=#c72c25]@&quot;admin&quot;[/color], [color=#c72c25]@&quot;*****&quot;[/color], [color=#b41ca4]nil[/color completion:^(JSONRPCMethodCall * methodCall,id result,NSError * error)

    {

    NSArray * tab = [/color][color=#7134aa]NSHTTPCookieStorage[/color][color=#000000] [/color]sharedHTTPCookieStorage[color=#000000 cookiesForURL:service.serviceURL];


    int i=[tab count];

    for(int j=0;j<=i;j++)

    {

    NSHTTPCookie * Cookie;

    Cookie = [tab objectAtIndex:j];

    if (Cookie [color=#401082]name[/color isEqualToString:@VHTSESSION])

    {

    NSLog(@" Voila la valeur du cookie: %@",[Cookie value]);


    service [color=#38595d]callMethodWithNameAndParams[/color]:[color=#c72c25]@&quot;get_token&quot;[/color], [color=#b41ca4]nil[/color completion:^(JSONRPCMethodCall * methodCall,id result,NSError * error)

    {

    NSString * resultat = result;

    NSLog(@Voila la valeur du token: %@",resultat);

    }

    ];

    }

    }

    }

    ];

    /// Do any additional setup after loading the view, typically from a nib.


    }



    voici le résultat sur le terminal :







    2012-04-12 15:03:47.845 vht2[2691:f803] Voila la valeur du cookie: 3go84vadpbol9gngaisp0g40s0

    2012-04-12 15:03:47.848 vht2[2691:f803] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 2 beyond bounds [0 .. 1]'

    *** First throw call stack:

    (0x13dc022 0x156dcd6 0x13c8d88 0x2721 0x9e22 0xa29a49 0xa27e84 0xa28ea7 0xa27e3f 0xa27fc5 0x96cf5a 0x39afa39 0x3a7c596 0x39a6120 0x3a7c117 0x39a5fbf 0x13b094f 0x1313b43 0x1313424 0x1312d84 0x1312c9b 0x12c57d8 0x12c588a 0x26626 0x220d 0x2175)

    terminate called throwing an exception(lldb)



    Donc en gros il récupère bien le cookie que je souhaite, mais il s'arrête et veux pas appeler la méthode get_token, qui est pourtant correctement appelé par moi.



    Comprend pas image/huh.gif' class='bbc_emoticon' alt='???' />??,
  • L'erreur est toute bête est très bien décrite dans le message d'erreur, tu as fait un appel de objectAtIndex sur un NSArray en lui demandant l'index 2 alors que la borne supérieur est 1



    Le problème viens de ta boucle...


    <br />
    int i=[tab count];<br />
    for(int j=0;j&lt;=i;j++)<br />
    {...<br />
    




    Tu lui dis ici d'incrémenter j tant qu'il est inférieur ou égal à  i. i quant à  lui représente le nombre d'objet total dans le tableau... Un tableau en informatique ça commence à  0 donc la borne supérieur est toujours le compte -1...



    Tu aurais du écrire j<i.
  • image/tongue.png' class='bbc_emoticon' alt=':P' />

    Ok je me cache !!!!!!!!!!!!!!!
  • Re-bonjour les gens,



    voila cette fois ci je souhaite définir tout ce que j'ai fait la-dessus dans une méthode qui me retournera un tableau contenant la valeur de mon cookie de session et de mon token.









    - (NSArray *) login

    {

    NSString * http=@"http://";;

    NSString * suite=@/auth/rpc.php;


    NSString * lien=[NSString stringWithFormat:@%@%@%@",http,self.adre,suite];

    NSURL * serviceURL = [NSURL URLWithString:lien];

    JSONRPCService * service = /color][color=#578187]JSONRPCService[/color][color=#000000] [/color]serviceWithURL[color=#000000]:serviceURL [/color]version[color=#000000]:[/color]JSONRPCVersion_2_0[color=#000000;


    service [color=#38595d]callMethodWithNameAndParams[/color]:[color=#c72c25]@&quot;login&quot;[/color], [color=#b41ca4]self[/color].[color=#7134aa]log[/color], [color=#b41ca4]self[/color].[color=#7134aa]pwd[/color], [color=#b41ca4]nil[/color completion:^(JSONRPCMethodCall * methodCall,id result,NSError * error)

    {

    NSArray * tab = [/color][color=#7134aa]NSHTTPCookieStorage[/color][color=#000000] [/color]sharedHTTPCookieStorage[color=#000000 cookiesForURL:service.serviceURL];


    int i=[tab count];

    for(int j=0;j<i;j++)

    {

    NSHTTPCookie * Cookie;

    Cookie = [tab objectAtIndex:j];

    if (Cookie [color=#401082]name[/color isEqualToString:@VHTSESSION])

    {

    NSString * resultat1;

    resultat1=color=#7134aa]NSString[/color] [color=#401082]stringWithFormat[/color]:[Cookie [color=#401082]value[/color];

    service [color=#38595d]callMethodWithNameAndParams[/color]:[color=#c72c25]@&quot;get_token&quot;[/color], [color=#b41ca4]nil[/color completion:^(JSONRPCMethodCall * methodCall,id result,NSError * error)

    {

    NSString * resultat2;

    resultat2=[NSString stringWithFormat:result];

    }

    ];

    }

    }

    }

    ];

    NSArray * tabLogin = [NSArray arrayWithObjects:resultat1, resultat2, nil];

    return tabLogin;

    }



    du coup il m'affiche pas mal d'erreur, le premier qui me dit que je ne peux pas utiliser la méthode value sur mon objet Cookie, car cette méthode est déjà  défini sur d'autre objet de mon framework de base et aussi à  l'avant dernière ligne ou je défini mon tableau tabLogin que l'utilisation de mes identificateurs ne sont pas déclaré.



    image/huh.gif' class='bbc_emoticon' alt='???' />
  • AliGatorAliGator Membre, Modérateur
    avril 2012 modifié #28
    Alors le premier problème je n'ai pas bien compris ce que tu veux dire.



    Le second problème par contre c'est normal. Tu déclares resultat1 et resultat2 dans des blocs entre accolades, donc ces variables n'existent qu'à  l'intérieur du bloc de variables. Ca c'est du C de base. Exemple :
    int i = 0;<br />
    // ...<br />
    if (i==5)<br />
    {<br />
      int j = 5;<br />
      // à  ce stade j est déclaré dans le bloc du &quot;if&quot; et donc n&#39;existe que dans ce périmètre<br />
      // ...<br />
      int k = j+1; // ok pas de problème<br />
    }<br />
    // à  ce stade, le bloc du &quot;if&quot; est fini, donc les variables déclarées à  l&#39;intérieur (dont j) n&#39;existent plus<br />
    int x = j+1; // bam, c&#39;est interdit, car j n&#39;existe plus il ne le connait plus.
    
    Du coup il faut que tu déclares les variables que tu veux utiliser au bon endroit (à  l'extérieur de ton bloc "if" dans mon exemple ci-dessus) pour qu'elles aient une visibilité pour tout le reste de la fonction et pour pouvoir y accéder à  la fin de ta fonction aussi.





    Bon ensuite une fois que tu auras fait ça, tu auras un autre problème, non plus lié à  du C de base, mais au blocks Objective-C, petite particularité des blocks ObjC qui capturent les variables, et qui font que par défaut tu ne peux pas modifier à  l'intérieur d'un block "^{ ... }" (comme ceux que tu mets en paramètre de "completion:") une variable qui a été déclarée à  l'extérieur de ce block. Si tu veux pouvoir modifier ces variables déclarées à  l'extérieur d'un block et capturées par ce block, il faut les déclarer avec le mot clé "__block" devant.
    __block NSString* result1;<br />
    <br />
    // blablabla<br />
    [[service callMethodWithNameAndParams:@&quot;login&quot;, self.log, self.pwd, nil] completion:^(JSONRPCMethodCall * methodCall,id result,NSError * error)<br />
    {<br />
    // blablabla<br />
    <br />
    result1 = ...<br />
    }];<br />
    // blabla<br />
    return result1; // ou arrayWithObjects:result1, ..., nil enfin ce que tu veux
    
  • Merci, visiblement j'ai plus d'erreur finalement en rajoutant les __block, par contre je ne peux toujours pas tester, car j'ai une autre erreur, je ne sais pas s'il est du à  la complétion, ou au moment ou j'affecte mon result à  ma variable ??





    - (NSArray *) login

    {

    NSString * http=@"http://";;

    NSString * suite=@/auth/rpc.php;


    NSString * lien=[NSString stringWithFormat:@%@%@%@",http,self.adre,suite];

    NSURL * serviceURL = [NSURL URLWithString:lien];

    __block NSString * valCookie;

    __block NSString * valToken;

    JSONRPCService * service = /color][color=#578187]JSONRPCService[/color][color=#000000] [/color]serviceWithURL[color=#000000]:serviceURL [/color]version[color=#000000]:[/color]JSONRPCVersion_2_0[color=#000000;


    service [color=#38595d]callMethodWithNameAndParams[/color]:[color=#c72c25]@&quot;login&quot;[/color], [color=#b41ca4]self[/color].[color=#7134aa]log[/color], [color=#b41ca4]self[/color].[color=#7134aa]pwd[/color], [color=#b41ca4]nil[/color completion:^(JSONRPCMethodCall * methodCall,id result,NSError * error)

    {

    NSArray * tab = [/color][color=#7134aa]NSHTTPCookieStorage[/color][color=#000000] [/color]sharedHTTPCookieStorage[color=#000000 cookiesForURL:service.serviceURL];


    int i=[tab count];

    for(int j=0;j<i;j++)

    {

    NSHTTPCookie * Cookie;

    Cookie = [tab objectAtIndex:j];

    if (Cookie [color=#401082]name[/color isEqualToString:@VHTSESSION])

    {



    valCookie=[Cookie value];

    service [color=#38595d]callMethodWithNameAndParams[/color]:[color=#c72c25]@&quot;get_token&quot;[/color], [color=#b41ca4]nil[/color completion:^(JSONRPCMethodCall * methodCall,id result,NSError * error)

    { // Too many arguments to method call, expected 1, have 2

    valToken=[NSString stringWithFormat:result];

    }

    ];

    }

    }

    }

    ];

    NSArray * tabLogin = color=#7134aa]NSArray[/color] [color=#401082]arrayWithObjects[/color]:valCookie, valToken, [color=#b41ca4]nil[/color;

    return tabLogin;





    Une idée ?
  • Lol, maintenant c'est plus cette erreur qui se produit, c'est une autre quand j'essaye d'exécuter la méthode et afficher le contenu de mon tableau, générer avec ma méthode login:





    2012-04-17 13:56:48.674 vht2[1080:f803] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 0 beyond bounds for empty array'

    *** First throw call stack:

    (0x13de022 0x156fcd6 0x13ca644 0xbbf7 0x2bbb 0xefa1e 0x4e401 0x4e670 0x4e836 0x5572a 0x26596 0x27274 0x36183 0x36c38 0x2a634 0x12c8ef5 0x13b2195 0x1316ff2 0x13158da 0x1314d84 0x1314c9b 0x26c65 0x28626 0x28ed 0x2855)

    terminate called throwing an exception(lldb)
  • zoczoc Membre
    Les message est pourtant clair, ton tableau est vide...
Connectez-vous ou Inscrivez-vous pour répondre.