web-dev-qa-db-fra.com

Analyser la réponse JSON avec AFNetworking

J'ai configuré une publication JSON avec AFNetworking dans Objective-C et j'envoie des données à un serveur avec le code suivant:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = @{@"name": deviceName, @"model": modelName, @"pin": pin};
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager.requestSerializer setValue:@"Content-Type" forHTTPHeaderField:@"application/json"];
[manager POST:@"SENSORED_OUT_URL" parameters:parameters

success:^(AFHTTPRequestOperation *operation, id responseObject)
{
    NSLog(@"JSON: %@", responseObject);
}

failure:^(AFHTTPRequestOperation *operation, NSError *error)
{
    NSLog(@"Error: %@", error);
}];

Je reçois des informations via la même demande et je souhaite envoyer les données à un NSString. Comment pourrais-je m'y prendre avec AFNetworking?

12
James

responseObject est un NSArray ou NSDictionary. Vous pouvez vérifier au moment de l'exécution à l'aide de isKindOfClass::

if ([responseObject isKindOfClass:[NSArray class]]) {
    NSArray *responseArray = responseObject;
    /* do something with responseArray */
} else if ([responseObject isKindOfClass:[NSDictionary class]]) {
    NSDictionary *responseDict = responseObject;
    /* do something with responseDict */
}

Si vous avez vraiment besoin de la chaîne du fichier JSON, vous pouvez vous en procurer en consultant operation.responseString.

28
Aaron Brager

Dans ce cas, lorsque le service Web répond avec JSON, AFNetworking procédera à la sérialisation pour vous et responseObject sera très probablement un objet NSArray ou NSDictionary

Un tel objet devrait vous être plus utile qu'une chaîne avec un contenu JSON.

8
RaffAl

Dans mon cas, ça ressemble à (peut-être que ça peut aider)

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager POST:url parameters:params
      success:^(AFHTTPRequestOperation *operation, id responseObject) {
          NSDictionary *jsonDict = (NSDictionary *) responseObject;
          //!!! here is answer (parsed from mapped JSON: {"result":"STRING"}) ->
          NSString *res = [NSString stringWithFormat:@"%@", [jsonDict objectForKey:@"result"]];
      } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
          //....
      }
 ];

Il serait également intéressant de vérifier le type d'objet de réponse (comme https://stackoverflow.com/a/21962445/3628317 answer)

5
levo4ka

Je trouve que cela fonctionne mieux pour AFHTTPClient sous-classe comme suit:

//  MyHTTPClient.h

#import <AFNetworking/AFHTTPClient.h>

@interface MyHTTPClient : AFHTTPClient

+ (instancetype)sharedClient;

@end

//  MyHTTPClient.m

#import "MyHTTPClient.h"

#import <AFNetworking/AFJSONRequestOperation.h>

static NSString *kBaseUrl = @"http://api.blah.com/yada/v1/";

@implementation MyHTTPClient

+ (instancetype)sharedClient {
    static id instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}

- (id)init {
    if (self = [super initWithBaseURL:[NSURL URLWithString:kBaseUrl]]) {
        self.parameterEncoding = AFJSONParameterEncoding;

        [self setDefaultHeader:@"Accept" value:@"application/json"]; // So AFJSONRequestOperation becomes eligible for requests.
        [self registerHTTPOperationClass:[AFJSONRequestOperation class]]; // So that it gets used for postPath etc.
    }
    return self;
}

@end

Les bits importants sont:

  • Définir 'Accepter' de manière à ce que AFJSONRequestOperation devienne éligible.
  • Ajout de AFJSONRequestOperation aux classes d'opération http.

Ensuite, vous pouvez l'utiliser comme ceci:

#import "MyHTTPClient.h"

@implementation UserService

+ (void)createUserWithEmail:(NSString *)email completion:(CreateUserCompletion)completion {
    NSDictionary *params = @{@"email": email};
    [[MyHTTPClient sharedClient] postPath:@"user" parameters:params success:^(AFHTTPRequestOperation *operation, NSDictionary *responseObject) {
        completion([responseObject[@"userId"] intValue], YES);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        completion(0, NO);
    }];
}

@end

La beauté de ceci est que votre responseObject est automatiquement analysé par JSON dans un dictionnaire (ou un tableau) pour vous. Très propre.

(ceci est pour afnetworking 1.x)

1
Chris