Question retour de requete JSON
Hiike
Membre
J'utilise le framework AliJSONRPC, qui fonctionne très bien, seulement j'ai un petit problème pour récupérer la réponse :
Je vous donne mon code
Ce code d'après ce que j'ai compris appelle la fonction :
Or mon NSLog renvoie hih (null) , j'aimerais récupérer des données en JSON
(Quand je fais NSString * rep = mc;
NSLog(@hih%@",mc); j'obtiens la réponse hih<JSONRPCMethodCall rpcGuest.getListe()>
et quand j'envoie cette methode rpcGuest.getListe() à mon serveur via une page javascript il me renvoie les données
Donc mon serveur est bien établi, le problème ne vient pas de là .
COmment puis je récupérer cette réponse avec mon programme?
Sachant que j'aimerais ensuite pouvoir traiter la réponse dans une data de la sorte :
POuvez vous m'expliquez pas à pas comment je récupére la réponse du serveur, je sais qu'il renvoie quelque chose j'ai la ligne
mais j'aimerais vraiment pouvoir accéder à ces données.
MErci beaucoup
Je vous donne mon code
NSURL * url = [[NSURL URLWithString: @"http://captainservicespot.appspot.com/guestbook/JSON-RPC"] retain];
JSONRPCService* serv = [JSONRPCService serviceWithURL:url version:JSONRPCVersion_1_0];
JSONRPCResponseHandler* h = [serv callMethodWithName: @rpcGuest.getListe parameters:nil];
[h setDelegate:self]; ????
>(ligne dont je ne suis pas sur)
Ce code d'après ce que j'ai compris appelle la fonction :
-(void)methodCall:(JSONRPCMethodCall*)mc didReturn:(id)ret error:(NSError*)err {
NSString * rep = ret;
NSLog(@hih%@",rep);
}
Or mon NSLog renvoie hih (null) , j'aimerais récupérer des données en JSON
(Quand je fais NSString * rep = mc;
NSLog(@hih%@",mc); j'obtiens la réponse hih<JSONRPCMethodCall rpcGuest.getListe()>
et quand j'envoie cette methode rpcGuest.getListe() à mon serveur via une page javascript il me renvoie les données
result ={"javaClass": "org.datanucleus.store.appengine.query.StreamingQueryResult", "list": [{"lastName": "BELKHEIR", "hireDate": {"time": 1276704486630, "javaClass": "java.util.Date"}, "javaClass": "guestbook.Conducteur", "firstName": "Elie", "key": {"id": 4001, "complete": true, "name": null, "javaClass": "com.google.appengine.api.datastore.Key", "parent": null, "kind": "Conducteur", "namespace": ""}}, {"lastName": "TORRES", "hireDate": {"time": 1276704487518, "javaClass": "java.util.Date"}, "javaClass": "guestbook.Conducteur", "firstName": "Fernando", "key": {"id": 5001, "complete": true, "name": null, "javaClass": "com.google.appengine.api.datastore.Key", "parent": null, "kind": "Conducteur", "namespace": ""}}, {"lastName": "HENRY", "hireDate": {"time": 1276864550287, "javaClass": "java.util.Date"}, "javaClass": "guestbook.Conducteur", "firstName": "Vinh", "key": {"id": 5002, "complete": true, "name": null, "javaClass": "com.google.appengine.api.datastore.Key", "parent": null, "kind": "Conducteur", "namespace": ""}}]}
Donc mon serveur est bien établi, le problème ne vient pas de là .
COmment puis je récupérer cette réponse avec mon programme?
Sachant que j'aimerais ensuite pouvoir traiter la réponse dans une data de la sorte :
NSMutableString * str = [[NSMutableString alloc] initWithData:data encoding:NSASCIIStringEncoding];
SBJSON * parser = [[SBJSON alloc] init];
NSArray * list = [parser objectWithString:str];
int i = 0;
for(NSDictionary * u in list) {
[monTableau insertObject:[u objectForKey:@firstName] atIndex:i];
[intTableau insertObject:[u objectForKey:@lastName] atIndex:i];
i++;
}
POuvez vous m'expliquez pas à pas comment je récupére la réponse du serveur, je sais qu'il renvoie quelque chose j'ai la ligne
warning: JSONRPCResponseHandler did receive a response but no delegate defined: the response has been ignored
mais j'aimerais vraiment pouvoir accéder à ces données.
MErci beaucoup
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
[Mode modo] Je me suis permis de séparer ton sujet, car il n'était pas vraiment en relation avec "NSProxy et warnings" mais plutôt avec mon framework, certes dont je parle dans cet autre sujet, mais qui n'est pas le sujet principal. [/Mode modo]
Pour ta question :
- Oui c'est bien comme cela qu'il faut faire pour l'appel. avec "[h setDelegate:self]" tu indiques que c'est self qui va devoir recevoir le message "methodCall:didReturn:error:", message que tu as implémenté ensuite.
NB : Si tu préfères que cela appelle une autre méthode que "methodCall:didReturn:error:", tu peux aussi la préciser en indiquant la "callback" à appeler. Dans ton cas dans un premier temps c'est pas utile, autant utiliser la callback par défaut, mais ça peut devenir utile si tu effectues plusieurs requêtes JSON-RPC différentes ayant le même delegate, pour traiter les réponses de ces différentes requêtes dans des méthodes séparées.
Sinon pour le traitement de la réponse :
- Ma classe se charge également du parsing de la réponse JSON retournée. Donc tu n'auras pas à utiliser SBJSON, le traitement par SBJSON est déjà prévu à l'intérieur de mon framework !
- Par exemple, à priori vu ce que te retourne ton WebService, tu devrais recevoir un NSDictionary en réponse dans le paramètre "result"
- Le plus simple est sans doute directement d'afficher les variables result et error et même leur classe, pour t'aider à y voir plus clair :
- Par contre il y a un truc que je ne comprends pas : tu appelles bien "setDelegate:", et tu dis même ce que te renvoie ton NSLog, ce qui sous-entend que la méthode "methodCall:... didReturn:... error:..." est bien appelée, non ? Pourtant tu dis avoir le warning "JSONRPCResponseHandler did receive a response but no delegate defined" ? (note, c'est peut-être un bug dans mon framework, mais j'ai pas souvenir d'avoir eu le cas pour ma part donc bon)
Et enfin, j'ai un gros doute là , la chaà®ne que tu as recopiée comme étant la réponse JSON de ton WebService, c'est pas strictemet celle qui est retournée, le vrai result est encapsulée dans un objet JSON au moins ?
Non parce que telle que tu l'as recopiée ici, c'est à dire si elle commence par "result = { ... }", alors ce n'est pas une réponse JSON valide du tout !
Une réponse JSON valide doit respecter la syntaxe JSON (si tu veux tester, il suffit de recopier la chaà®ne que te retourne ton serveur sur un validateur JSON, comme http://www.jsonlint.com/, et de cliquer sur "Validate" pour qu'il vérifie si c'est une chaà®ne JSON valide) : la réponse d'un serveur JSON-RPC doit être au moins de la forme : Donc retourner un object JSON (note les accolades ouvrantes et fermantes au début et à la fin), et chaque clé de cet objet JSON (ici il n'y en a qu'une, "result") a sa valeur correspondante après des ":" (et non un "=").
C'est sans doute pour cela que ta variable "ret" est nil d'ailleurs, parce que SBJSON (que mon framework utilise pour parser la réponse) n'arrive pas à décoder la chaà®ne que tu retournes comme un objet JSON puisque tu ne respectes pas cette syntaxe.
(Bon par contre mon framework devrait appeler la méthode de delegate indiquant une erreur de parsing, pour le coup... enfin si tu l'as implémentée)
J'obtiens :
Alors je ne sais pas ce que je fais de pas correct, parce que en fait mon serveur renvoie bien un JSON , en fait le result c'était un texte que j'avais écris pour afficher le result : (c'est dans l'alert).
Ma requete javascript donne bien ce résultat JSON qu'il faut que je récupére..
Le ret devrais me renvoyer un NSDictionnary ? C'est bien ca ? Au lieu de mettre null...
Est ce que cela peut être la version du JSONRpc? j'ai l'impression que je ne suis pas loin, j'ai bien suivi la documentation..
Donc ce genre d'erreur est du coup propre à ton WebService : le code 591 est un code spécifique à ton WebService, je ne peux pas te dire à quoi il correspond puisque c'est une erreur serveur, dont la signification du code est propre à ton serveur. Ca peut être un truc comme "méthode inexistante" (si tu essayes d'appeler une méthode qui n'existe pas sur ton WebService) " bien que pour cette erreur en particulier il y ait un code réservé " ou un autre truc encore...
Mais comme pour tout objet NSError, tu as un dictionnaire dit "userInfo" qui peut contenir diverses informations supplémentaires sur l'erreur (qui ne se résume pas qu'à son domaine et son code d'erreur : cf le "Error Handling Programming Guide" cité plus haut, section "Domain Specific Keys").
Ainsi (et toujours comme indiqué dans la même section de la doc, ou encore ici sur le wiki) tu peux avoir plus d'infos sur l'erreur à proprement parler que t'a renvoyé ton serveur justement en regardant ce que contient le NSDictionary "userInfo", et en particulier le JSON d'erreur que t'a renvoyé ton WebService, qui se trouve dans la clé [tt]JSONRPCErrorJSONObjectKey[/tt] du userInfo de l'erreur :
Avec ce log tu pourras voir exactement l'erreur que te renvoie ton WebService, qui manifestement ne te renvoie pas la même chose quand tu appelles ton WebService en JSON-RPC avec mon framework et quand tu l'appelles directement avec tes pages de test contenant ton javascript, depuis je ne sais pas quel autre moyen.
C'est peut-être en effet la version de JSON-RPC que tu utilises qui ne colle pas : mon framework implémente les versions 1.0, 1.1 et 2.0 de JSON-RPC (en suivant les RFC et specs trouvées sur le site officielle), mais si tu appelles un WebService ne supportant que JSON-RPC 2.0 (et pas le 1.0) par exemple, en disant à mon framework (quand tu crées le JSONRPCService) que c'est du JSONRPCVersion_1_0 et non JSONRPCVersion_2_0, ton WebService peut retourner une erreur éventuellement oui... selon la ou les versions de JSONRPC qu'il implémente.
De toute façon les logs et informations se trouvant dans le userInfo de la NSError t'en diront bien plus sur ton problème.
C'est donc que la méthode n'est pas reconnue...Pourtant mon client Javascript la trouve bien pourtant...
Ou le JSONRpcClient est implémenté de la sorte :
Et je l'appelle comme cela :
Le callMethodWithName lit juste le nom d'une méthode ?
Une dernière question, pour avoir ma réponse JSOn, vous voyez dans le quote plus haut que j'utilise toJSON(result).
C'est un Marshall object que je récupére directement, avant de le convertir en JSON
Votre fonction callMethodWIthName fait elle directement cette conversion, pensez vous que l'erreur peut venir de là , ou c'est vraiment
la méthode qui n'est pas trouvée ?
Merci, beaucoup pour votre aide
Donc oui c'est vraiment la méthode qui n'est pas trouvée d'après le message (s'il y avait un problème JSON genre mauvaise encapsulation ou erreur de parsing, ce n'est pas cette erreur que tu aurais... (a moins que ton WebService ne fasse pas les vérifications d'erreur d'usage, genre ne vérifie/traite même pas les erreurs genre "Invalid Request" qui sont pourtant standard en JSON-RPC et ne te retourne alors pas comme il devrait le code d'erreur adéquat mais un mauvais code d'erreur, mais là ça serait quand même très très louche, je doute que ça soit le cas). De même, s'il recevait une requête au format JSON-RPC 1.0 alors qu'il s'attendait à du 1.1 ou du 2.0... ou vice-versa, et ne savait pas traiter la requête qu'il reçoit, normalement dans ce cas c'est un autre type d'erreur qu'il te retournerait, pas une erreur custom. 591.
Ceci dit ce qui est bizarre, c'est que le code d'erreur "Méthode non trouvée" est une erreur standard de JSON-RPC. Donc c'est pas normal que dans ce genre de cas, ton serveur retourne une erreur avec pour message "method not found", mais avec un code d'erreur 591 alors que le code d'erreur officiel pour ce cas typique de méthode non trouvée est le code -32601, d'après la norme officielle de JSON-RPC... Donc louche ce point côté serveur...
Sinon, tu as bien fourni la bonne URL lorsque tu as construit le WebService ? Tu ne tapes pas par erreur sur un autre service JSON-RPC (chez lequel la méthode n'existerait pas, là -bas) ?
Tu utilises quoi côté serveur pour mettre en place ton WebService ?
Pour plus d'infos, je t'avais déjà indiqué je crois le sujet dédié concernant mon framework, ici : tu y trouveras peut-être d'autres éléments de réponse ?
Et enfin dernière question, ton WebService ne nécessite pas une authentification ? (Pour l'heure je n'ai pas prévu dans mon framework de gérer les authentifications genre Basic ou Digest, ça viendra sans doute plus tard s'il y a forte demande et si j'ai du temps)
Juste comment puis je voir/afficher la requête que vous envoyez au serveur ?
Quelque chose comme cela ?? :
Ou sinon côté webservice j'ai :
L'initializer de Jsonrpc, celui qui va traiter le rpcGuest :
Celui ci appelle la classe conducteurManager (java) qui donne :
C'est avec cela que mon webservice est mis en place, et voilà ce que devrait répondre le getListe.
Y a t'il quelque chose de non compatible ?
Ensuite, je n'ai pas laissé de logs dans mon framework, mais comme d'après ce que tu me dis tout semble plutôt correct sur ta config, tu peux peut-être mettre un breakpoint lors de l'appel à "callMethodWithName:parameters:", puis rentrer dedans en mode debug. Cette méthode construit un objet JSONRPCMethodCall en passant le nom de la méthode et les paramètres que tu as fourni à "callMethodWithName:parameters:", puis appelle cette JSONRPCMethodCall.
Tu peux donc déjà voir en mode debug pas à pas, si le JSONRPCMethodCall est bien construit avec les paramètres attendus. Ca va rentrer ensuite dans la méthode "callMethod:" de la classe JSONRPCService, où il transforme le JSONRPCMethodCall en chaà®ne JSON (dans la variable jsonStr), tu pourras également voir sa valeur.
Tu peux aussi le voir dans la méthode de delegate quand tu reçois la réponse (avec donc l'erreur retournée par le serveur) en mettant : qui va t'afficher la chaà®ne JSON qui a été envoyée au serveur pour obtenir cette réponse/erreur de la part du serveur.
[EDIT] Je viens de faire le test en reprenant ton code avec donc ton URL et ton nom de méthode cité dans le premier message, cela envoie exactement ceci au serveur : J'ai essayé en appelant ton service comme un WebService JSON-RPC 1.0 et 2.0 (le JSON envoyé n'est pas tout a fait le même, la norme a changé entre ces versions) et ça ne marche pas mieux... bizarre.
Sais-tu à quoi ressemble le JSON que ton client (celui qui semble marcher) envoie, lui, à ton WebService, histoire de comparer et mieux comprendre le souci ?
(en fait en local tout fonctionnait depuis le début). Je te remercie ENORMEMENT, de la peine que tu t'es donné.
Merci encore....
En effet, je dois envoyer une requête genre :
Le truc c'est que je n'ai pas accès au code du service et que je ne vois pas quoi mettre dans callMethodWithName.
Si je rentre directement l'url dans un navigateur, j'ai tout le fichier JSON qui s'affiche, et c'est bien ça que j'aimerai pour mon app iPhone .
Une idée ?
Un service JSON-RPC c'est un WebService qui propose de multiples méthodes (procédures) que l'on appelle (call) justement à distance (remote) via le réseau (d'où le nom RPC = Remote Procedure Call). Pour appeler ces méthodes, il y a une syntaxe particulière à respecter lorsque l'on envoie la requête au WebService (lui envoyer une chaà®ne JSON formatée d'une certaine manière pour lui dire quelle méthode du WebService on veut appeler, etc), partie dont se charge mon framework (entre autres choses)
Un WebService JSON-RPC, qui propose donc plusieurs procédures que l'on peut appeler ainsi à distance, liste alors en général toutes les procédures qu'il propose (il arrive que si l'on requête le WebService JSON-RPC sans aucune requête d'appel à une procédure du WebService, par défaut il retourne la liste des procédures disponibles, si le serveur est configuré comme tel ce qui est le cas de certains... sinon la liste est en général accessible sur le site Web qui décrit l'API, etc)
Si tu as directement le résultat du JSON dans ton navigateur dès que tu tapes ton URL dans Safari par exemple, ce n'est alors à priori pas du JSON-RPC, mais juste un service unique qui retourne sa réponse en JSON. C'est une page retournant du JSON, pas un WebService JSON-RPC.
Dans ce cas, si tu as une page unique avec laquelle t'interfacer, et pas besoin d'indiquer en RPC quelle procédure tu veux appeler quand tu envoies ta requête à l'URL et tout... alors tu n'as pas besoin de mon framework, tu as juste besoin de faire une requête à l'URL sans aucun paramètre particulier, récupérer la réponse (le texte JSON), et utiliser SBJSON pour le parser. Donc SBJSON (que j'utilise entre autres dans mon framework JSON-RPC justement) devrait te suffire pour ton besoin.
Merci encore pour tes explications ^^