AFNetworking avec AFHTTPClient avec AFJSONRequestOperation // Problèmes de type MIME

J'ai essayé de maîsortingser AFHTTPClient dans l'instance spécifique d'envoi d'une request à un service basé sur REST qui requirejs l'authentification OAuth. Je n'ai aucun problème avec la création de l'authentification OAuth en utilisant GTMOAuth.

Je peux également gérer avec succès les parameters pour envoyer la requête et get une réponse JSON bien formée en utilisant un NSMutableURLRequest pavé manuellement et à la fois AFJSONRequestOperation et un NSURLConnection. Ces deux derniers mécaniciens étaient ma vérification de santé mentale que je touchais le service correctement.

Je reçois une réponse en utilisant

[AFHTTPClient HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject)] 

mais peu importe quoi – il est interprété comme du text / plaine. La class de l'object renvoyé est __NCFData.

Pas de bueno.

Ce bit de code ne veut pas renvoyer une réponse qui est un dictionary de n'importe quel type.

 - (IBAction) testFlickr { // marshall parameters NSSsortingng *urlStr = @"http://api.flickr.com/"; NSURL *url = [NSURL URLWithSsortingng:urlStr]; AFHTTPClient *client = [[AFHTTPClient alloc]initWithBaseURL:url]; [client registerHTTPOperationClass:[AFJSONRequestOperation class]]; [client setParameterEncoding:AFJSONParameterEncoding]; NSDictionary *params = [[NSDictionary alloc]initWithObjectsAndKeys:@"json", @"format", @"66854529@N00", @"user_id", @"1", @"jsoncallback", nil]; NSSsortingng *path = [[NSSsortingng alloc]initWithFormat:@"services/rest/?method=flickr.people.getPhotos"]; NSMutableURLRequest *af_request = [client requestWithMethod:@"GET" path:path parameters:params]; // flickrAuth instance variable is an instance of GTMOAuthAuthentication [self.flickrAuth authorizeRequest:af_request]; [client setAuthorizationHeaderWithToken:[self.flickrAuth accessToken]]; [client setDefaultHeader:@"Accept" value:@"application/json"]; [client requestWithMethod:@"GET" path:path parameters:params]; LOG_FLICKR_VERBOSE(0, @"Can Authorize? %@", ([self.flickrAuth canAuthorize] ? @"YES":@"NO")); LOG_FLICKR_VERBOSE(0, @"%@", client); // first way of trying.. AFHTTPRequestOperation *af_operation = [client HTTPRequestOperationWithRequest:af_request success:^(AFHTTPRequestOperation *operation, id responseObject) { NSSsortingng *str = [[NSSsortingng alloc] initWithData:responseObject encoding:NSUTF8SsortingngEncoding]; LOG_FLICKR_VERBOSE(0, @"Weird af_operation semantics, but.. %@", str); LOG_FLICKR_VERBOSE(0, @"Weird af_operation semantics returns %@", [responseObject class]); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { // LOG_FLICKR_VERBOSE(0, @"Weird af_operation semantics, error.. %@", error); }]; [af_operation start]; } 

Cette request va bien. Les données de réponse sont ce que je m'attendais, mais ce n'est pas une class de dictionary.

Je préfère continuer à utiliser les methods de AFHTTPClient (par opposition, par exemple, à [AFJSONRequestOperation JSONRequestOperationWithRequest]) afin que je puisse utiliser les methods d'accessibilité de AFHTTPClient et ainsi de suite.

Étrangement (pour moi, au less) si je fais la request comme ceci:

 NSMutableURLRequest *aj_request = [client requestWithMethod:@"GET" path:path parameters:params]; [self.flickrAuth authorizeRequest:aj_request]; AFJSONRequestOperation *aj_operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:af_request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { LOG_FLICKR_VERBOSE(0, @"AFJSONRequestOperation %@", JSON); } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) { LOG_FLICKR_VERBOSE(0, @"AFJSONREquestOperation Error %@", error); }]; [aj_operation start]; 

Il échoue avec un "401" car il attendait application / json dans l'en-tête de réponse et pense plutôt qu'il est reçu

Mais, si je fais la request comme ceci:

 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[[NSURL alloc]initWithSsortingng:@"http://api.flickr.com/services/rest/?method=flickr.people.getPhotos&format=json&user_id=66854529@N00&nojsoncallback=1"]]; [self.flickrAuth authorizeRequest:request]; AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { LOG_FLICKR_VERBOSE(0, @"Success Flickr =========\n%@ %@", JSON, [JSON valueForKeyPath:@"photos.total"]); /////handler(JSON, nil); } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) { LOG_FLICKR(0, @"URL Was %@", url); LOG_FLICKR(0, @"Failed Flickr ==========\n%@ %@", error, JSON); /////handler(nil, error); }]; [operation start]; 

Cela fonctionne bien, y compris les JSON, des données formées par dictionary.

Dans le premier cas, j'utilise AFHTTPClient pour produire le NSMutableURLRequest. Dans le second cas, je crée le NSMutableURLRequest moi-même. Dans les deux cas j'utilise AFJSONRequestOperation pour envoyer la requête en laissant le seul coupable du problème (à part moi-même ..) AFHTTPClient.

Dans le premier exemple que je peux get au travail, il ne renvoie pas de données JSON-y.

Dans le deuxième exemple, AFHTTPClient semble créer un NSMutableURLRequest qui échoue de manière flagrante – mais (AFAICT) la même URL réussit lorsque cette URL est créée "à la main" en utilisant [NSMutableURLRequest requestWithURL].

Je me request – qu'est-ce qui me manque quand j'utilise AFHTTPClient?

Aidez-moi?

Dans votre premier exemple de code, il semblerait que vous fassiez NSMutableURLRequest *af_request = [client requestWithMethod:@"GET" path:path parameters:params]; puis en définissant les en-têtes par défaut après. Les en-têtes par défaut ne sont appliqués qu'aux requests créées après leur spécification. Peut-être que c'est là que les choses vont mal.

En outre, cette erreur 401 peut se plaindre de son type de contenu, mais 401 est un code d'état d'erreur, ce qui signifie que vous n'êtes pas authentifié.

J'ai fini par enlever tous les parameters d'en-tête pour isoler le problème, mais cela n'a fait aucune différence. Examiner la réponse de très près m'a donné un indice. Alors que Flickr renvoie "JSON" il n'est pas non-pelucheux, il semble et nécessite un réglage de l'un des parameters. J'avais envoyé jsoncallback = 1 mais ça devrait être nojsoncallback = 1. Une fois que j'ai corrigé ce paramètre, AFJSONRequestOperation gère correctement la réponse et parsing le JSON.

Mon dernier code ressemble à ceci (pour les autres, nb le paramètre nojsoncallback = 1)

 - (IBAction)testFlickrAFJSON:(id)sender { // marshall parameters NSSsortingng *urlStr = @"http://api.flickr.com/"; NSURL *url = [NSURL URLWithSsortingng:urlStr]; //NSDictionary *params = [[NSDictionary alloc]initWithObjectsAndKeys:@"json", @"format", @"66854529@N00", @"user_id", nil]; NSDictionary *params = [[NSDictionary alloc]initWithObjectsAndKeys:@"json", @"format", @"66854529@N00", @"user_id", @"1", @"nojsoncallback", nil]; NSSsortingng *path = [[NSSsortingng alloc]initWithFormat:@"services/rest/?method=flickr.people.getPhotos"]; AFHTTPClient *client = [[AFHTTPClient alloc]initWithBaseURL:url]; NSMutableURLRequest *af_request = [client requestWithMethod:@"GET" path:path parameters:params]; [self.flickrAuth authorizeRequest:af_request]; LOG_FLICKR_VERBOSE(0, @"Can Authorize? %@", ([self.flickrAuth canAuthorize] ? @"YES":@"NO")); AFJSONRequestOperation *af_operation_2 = [AFJSONRequestOperation JSONRequestOperationWithRequest:af_request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { LOG_FLICKR_VERBOSE(0, @"AFJSONRequestOperation Alt %@", JSON); LOG_FLICKR_VERBOSE(0,@"AFJSONRequestOperation Alt response MIMEType %@",[response MIMEType]); } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) { LOG_FLICKR_VERBOSE(0, @"AFJSONREquestOperation Alt Error %@", error); NSHTTPURLResponse *resp = [[error userInfo] valueForKey:AFNetworkingOperationFailingURLResponseErrorKey]; LOG_FLICKR_VERBOSE(0,@"AFJSONRequestOperation Alt Error response MIMEType %@",[resp MIMEType]); }]; [af_operation_2 start]; }