RestKit, post en URLEncode, et mapper les réponses
Bonjour à tous,
J'ai un gros soucis, sur une requête POST en utilisant RestKit.
Ce que je souhaite faire : Une requête POST toute bête sans JSON, donc en URLEncode et qui mappe le retour qui lui est en JSON.
Je peux utiliser [manager.HTTPClient postPath:......], sauf que cette méthode ne permet pas de mapper le retour. Donc j'utilise la méthode [manager postObject].
Voici la version simple de mon code (donc sans le retour qui est mappé, car pour l'instant on s'en moque) :
// URL
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[monURL];
RKObjectMapping *requestMapping = [RKObjectMapping requestMapping];
[requestMapping addAttributeMappingsFromArray:@[;@key,@seller]];
RKRequestDescriptor *requestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:requestMapping objectClass:[ScanClass class] rootKeyPath:nil method:RKRequestMethodPOST];
NSIndexSet *statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful);
RKResponseDescriptor *responseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:orderProductMapping method:RKRequestMethodPOST pathPattern:monURL keyPath:@data.orders statusCodes:statusCodes];
RKObjectManager *manager = [RKObjectManager managerWithBaseURL: [NSURL URLWithString:[monURL]];
// En commentaire, car il s'en fou de toute façon, il le prend pas en compte
//[manager addRequestDescriptor:requestDescriptor];
//[manager addResponseDescriptor:responseDescriptor];
/*[manager setRequestSerializationMIMEType:RKMIMETypeFormURLEncoded];
[manager setAcceptHeaderWithMIMEType:RKMIMETypeFormURLEncoded];
manager.requestSerializationMIMEType =
RKMIMETypeFormURLEncoded;*/
//[[manager HTTPClient] setDefaultHeader:@Content-Type value:@application/x-www-form-urlencoded];
// J'ai créé une petite class pour tester l'envoi de l'info.
ScanClass *scanValues = [[ScanClass alloc] initWithValues:@order/114 ];
[[RKObjectManager sharedManager] postObject:scanValues path:@"" parameters:nilsuccess:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
NSLog(@OK);
} failure:^(RKObjectRequestOperation *operation, NSError *error)
{
NSLog(@KO);
}];
Or c'est là qu'il y a un soucis, car j'envoie au serveur la chose suivante :
{"key":"order/114"}
Alors que je devrais envoyer la chose suivante :
key=order%2F114
De plus, dans la requête qui part on voit bien ça :
Content-Type = "application.x-www-form-urlencode; charset=utf-8";
Donc cela devrait marcher...
C'est ultra bizarre, surtout que dans la documentation, c'est bien marqué que le comportement par défaut c'est d'envoyer en URLEncode, comme je le souhaite.
J'ai essayé de forcer le MIMETYPE, et il s'en fou royalement
(la documentation ici : http://restkit.org/api/latest/Classes/RKObjectManager.html#//api/name/requestSerializationMIMEType)
Donc ma question c'est : qu'est ce que je fais mal, qu'ai-je oublié ?
Bref merci de m'aider avec un morceau de code si possible
Merci à tous,
Réponses
Tu utilises RestKit.
Bon, OK, je trolle, et je n'ai pas de réponse à la question, mais mon expérience de RestKit, c'est qu'on l'utilise en se disant "il y a une pente d'apprentissage mais je gagnerai du temps après", mais qu'on ne gagne jamais de temps.
Pour moi, la lib souffre de gros problèmes de conception, mais le principe même n'est pas bon parce qu'il n'y a rien de tel qu'un standard REST.
Tout le temps que tu gagneras à ne pas écrire de code pour décomposer les URL, tu le perdras trois fois à écrire le routage dans sa syntaxe incompréhensible. Tout le temps que tu gagneras à ne pas écrire du code de mapping JSON, tu le perdras trois fois à tenter de corriger ses erreurs de mapping JSON. Et puis, là tu es sur un problème classique avec RestKit d'encodage, alors que tu l'aurais déjà réglé 12 fois à la main.
Après deux semaines passées avec RestKit, j'ai lâché l'affaire et je n'ai jamais regretté ma décision.
Au début on a utilisé RESTKit sur un projet en se disant c'est bien c'est carré ça va gagner du temps. Bilan, à un moment notre WS sortait un poil du cadre de ce que RESTKit impose (comme toi avec ton POST + URLEncode sans body) et aucune solution viable sans tout casser.
On a été obligé un fine d'abandonner RESTKit et de faire un refactoring d'une grosse partie du code à cause de lui. Bilan : des heures de perdues et un très mauvais souvenir de ce framework qui semblait pourtant pratique de prime abord...
Bon franchement merci pour vos retours.
Je me permets d'ajouter que je partage totalement votre point de vue. Là ou j'ai gagné du temps, j'en ai perdu énormément en cherchant sur internet une solution à cette librairie.
Elle impose énormément de contrainte, et la doc est terriblement mal foutue. Apparemment la version 0.10 était curieusement moins cadrée, donc permettait de faire ce qu'on voulait (peu ou prou).
Par contre, je souhaiterais quand même avoir une réponse, car c'est totalement incompréhensible le comportement de la librairie là .
Et mapper tous les objets à la main, me fait gagner du temps. Même si j'en ai perdu 10 fois plus à chercher une solution
Une aide serait grandement appréciée
Pourquoi ne débogues-tu pas REStkit pour voir pourquoi il ignore ton paramètre URLEncode ?
Une recherche sur "requestSerializationMIMEType", un point d'arrêt et hop.
En général, je me méfie toujours du coût caché d'utilisation d'une librairie.
Mais quitte à utiliser des librairies, je préfère en utiliser plusieurs petites que je pourrai modifier plutôt qu'une grosse qui fait tout mais dont je vais être complètement dépendant.
Autrement dit des librairies ou du code externe pour du code tactique, ok, mais pas pour le code stratégique (la structure), non.
Dans ton cas, cela serait une "librairie" pour encoder en URLEncode un dictionaire (il vaut mieux utiliser du code existant car il y a des subtilités).
Une autre pour l'envoie en http, et une autre pour le décodage json (quoique maintenant c'est intégré dans iOS).
Et la glue entre tout ça tu l'as fait à la main car cela te permet de comprendre ce qui se passe et de modifier l'agencement.
Autre règle : si j'ai le temps, je regarde un peu le code et les API pour voir si ça me parle, si je ne comprends pas le principe ou si c'est trop intelligent pour moi, j'essaye d'en trouver une autre.
Bah par contre là pour les 3 points que tu as cité aucune lib n'est nécessaire. Le SDK iOS fournit tout ce qu'il faut tant pour l'URLEncode (cf NSString) que pour le HTTP (NSURLConnection/NSURLSession) que pour le JSON. A la limite tu peux utiliser AFNetworking qui gère toute la chaà®ne (tu vas me dire c'est une grosse librairie et je viens de te dire d'éviter de dépendre de librairies trop "qui font tout" mais bon AFN est éprouvé et approuvé et connue pour être bien foutue donc elle ça va) mais tu peux aussi te contenter de ce que tu as dans le SDK iOS qui couvre déjà tout ce qu'il faut.
Oui c'est vrai d'ailleurs je n'utilise pas AFN en général.
En ce qui concern URLEncode, je me souviens avoir eu des soucis avec [NSString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] car elle ne remplace pas certains caractères spéciaux (/, &).
- et depuis iOS7 ou 8 je sais plus (voir la doc) il y a une methode de NSString voisine de celle que tu as citée mais qui permet de préciser le NSCharacterSet des caractères autorisés/à encoder ou non
https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/#//apple_ref/occ/instm/NSString/stringByAddingPercentEncodingWithAllowedCharacters: