wake-up-neo.net

Analysieren Sie die JSON-Antwort mit AFNetworking

Ich habe einen JSON-Beitrag mit AFNetworking in Objective-C eingerichtet und sende Daten mit folgendem Code an einen Server:

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);
}];

Ich erhalte Informationen über dieselbe Anfrage und möchte die Daten an eine NSString senden. Wie würde ich das mit AFNetworking machen?

12
James

responseObject ist entweder ein NSArray oder ein NSDictionary. Sie können zur Laufzeit mit isKindOfClass: prüfen:

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 */
}

Wenn Sie wirklich den String des JSON benötigen, können Sie ihn unter operation.responseString abrufen.

28
Aaron Brager

Wenn der Webservice mit JSON antwortet, führt in diesem Fall die AFNetworking die Serialisierung für Sie durch und die responseObject ist höchstwahrscheinlich entweder ein NSArray- oder ein NSDictionary-Objekt. 

Ein solches Objekt sollte für Sie nützlicher sein als eine Zeichenfolge mit JSON-Inhalt.

8
RaffAl

In meinem Fall sieht es so aus (vielleicht kann es helfen)

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) {
          //....
      }
 ];

Es wäre auch gut, den Typ des Antwortobjekts zu überprüfen (wie https://stackoverflow.com/a/21962445/3628317 answer).

5
levo4ka

Ich finde, es funktioniert am besten, AFHTTPClient wie folgt zu subklassieren:

//  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

Die wichtigen Bits sind:

  • Setzen Sie das 'Accept' so, dass AFJSONRequestOperation berechtigt wird.
  • Hinzufügen von AFJSONRequestOperation zu den http-Operationsklassen.

Dann können Sie es wie folgt verwenden:

#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

Das Schöne daran ist, dass Ihr responseObject für Sie automatisch in ein Wörterbuch (oder ein Array) geparst wird. Sehr sauber.

(dies ist für afnetworking 1.x)

1
Chris