Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON Response in postPath AFHTTPClient

I just switched to RestKit 0.2 and I am currently using the new "HttpClient" which is basically a AFHTTPClient. I have this line of code:

RKObjectManager* objectManager = [RKObjectManager sharedManager];
NSDictionary* params = [[NSDictionary alloc] initWithObjectsAndKeys: login, @"username", password, @"password", nil];

[[objectManager HTTPClient]postPath:@"users/login/?format=json" parameters:params
    success:^(AFHTTPRequestOperation *operation, id responseObject)
    {
        //reponseObject vs operation.response
        NSLog(@"%@", responseObject);
    }
    failure:^(AFHTTPRequestOperation *operation, NSError *error)
    {
        NSLog(@"ERROR");
    }];

This POST calls return a JSON response in the form: {"api_key":"....","username":"...."}. As simple as that.

Before switching to 0.2, I was able to get the api_key key in the response by doing:

 [[RKClient sharedClient] post:@"/users/login/?format=json" usingBlock:^(RKRequest *request)
 {
    request.onDidLoadResponse = ^(RKResponse *response)
    {
        id parsedResponse = [response parsedBody:NULL];
        NSString *apiKey = [parsedResponse valueForKey:@"api_key"];
    }
  }.....];

http://restkit.org/api/master/Classes/RKResponse.html

But now, I can't do that and if I do a NSLog on the responseObject, I get:

<7b227265 61736f6e 223a2022 41504920 4b657920 666f756e 64222c20 22617069 5f6b6579 223a2022 61356661 65323437 66336264 35316164 39396338 63393734 36386438 34636162 36306537 65386331 222c2022 73756363 65737322 3a207472 75657d>

And the weird thing is that if I do:

        NSLog(@"%@", operation.responseString);

I do have the JSON (in NSString) showing up.

So two questions:

1) Why is printing the responseObject showing me HEX code, and not the actually JSON response?

2) Why if I do operation.responseString it is showing the actual Response Object? Is there a way to get the actual data in ResponseObject after being parsed from the JSON?

like image 791
abisson Avatar asked Nov 14 '12 17:11

abisson


3 Answers

AFNetworking should instantiate a AFJSONRequestOperation. Probably it creates a basic AFHTTPRequestOperation instead (check [operation class]) resulting in a NSData object as response.

Make sure you register the operation class in the init method of your AFHTTPClient subclass (initWithBaseURL):

[self registerHTTPOperationClass:[AFJSONRequestOperation class]];

// Accept HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
[self setDefaultHeader:@"Accept" value:@"application/json"];

You could also try to use AFJSONRequestOperation directly like this:

NSURLRequest *request = [[objectManager HTTPClient] requestWithMethod:@"POST" path:@"users/login/?format=json" parameters:params];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
    NSLog(@"JSON: %@", JSON);
} failure:nil];
[[objectManager HTTPClient] enqueueHTTPRequestOperation:operation];
like image 157
Felix Avatar answered Nov 20 '22 02:11

Felix


What you are seeing, if I'm not mistaken, is the raw bytes from the NSData that is given to you when your success block is called.

The hex you posted reads:

{"reason": "API Key found", "api_key": "a5fae247f3bd51ad99c8c97468d84cab60e7e8c1", "success": true}

The reason the second NSLog shows you what you want is that the %@ format string calls the description (correct me if I'm wrong here, SO) of the object you pass it and the NSData probably knows it is a string underneath.

So, on to how to get the JSON. It is really rather simple. Once you have your response object, you can do something like this:

NSDictionary* jsonFromData = (NSDictionary*)[NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:&error];

What this will do for you is use return an NSDictionary which encodes the root object in the JSON and then each value in the dictionary will be of the type NSString, NSNumber, NSArray, NSDictionary, or NSNull. See NSJSONSserialization for documentation.

The NSJSONReadingMutableContainers makes the dictionaries and arrays mutable. It's just a leftover from my code.

Hopefully you're on iOS 5 or later, or you'll need to find another solution for the parsing.

like image 38
DanBlakemore Avatar answered Nov 20 '22 02:11

DanBlakemore


success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSData *responseData = operation.HTTPRequestOperation.responseData;
    id parsedResponse = [RKMIMETypeSerialization objectFromData:responseData    MIMEType:RKMIMETypeJSON error:nil];
    NSString *apiKey = [parsedResponse valueForKey:@"api_key"]
}
like image 3
Christian Avatar answered Nov 20 '22 04:11

Christian