Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AFNetworking returns a _NSCFData object instead of JSON

Tags:

afnetworking

I'm sending the following message to an instance of AFHTTPClient. I expect the success block to be sent a Foundation object (a dictionary) but the debugger shows me that JSON is a _NSCFData object. This question on SO states that I need to set the Accept header to 'application/json'. Well, I'm doing that but AFNetworking still is not decoding the JSON in the response body. If I decode the json myself using NSJSONSerialization I get an NSDictionary as I expect. What am I doing wrong?

[client setDefaultHeader:@"Accept" value:@"application/json"];
[client postPath:@"/app/open_connection/"
  parameters:params
     success:^(AFHTTPRequestOperation *operation, id JSON) {
         NSLog(@"successful login! %@", [JSON valueForKeyPath:@"status"]);
     }
     failure:^(AFHTTPRequestOperation *operation, NSError *error) {
         NSLog(@"error opening connection");
         NSAlert *alert = [NSAlert alertWithError:error];
         [alert runModal];
     }
];

Note: I'm programming the server in Python using Django. The content type of the response is 'application/json'

like image 488
Mike T Avatar asked Aug 05 '12 07:08

Mike T


2 Answers

When you're working with AFHTTPClient and a JSON API, you will typically need to set all three of these settings:

httpClient.parameterEncoding = AFJSONParameterEncoding;
[httpClient setDefaultHeader:@"Accept" value:@"application/json"];
[httpClient registerHTTPOperationClass:[AFJSONRequestOperation class]];

Now when you make requests using your client, it will know to parse the response as JSON.

[httpClient postPath:@"/app/open_connection/"
          parameters:params
             success:^(AFHTTPRequestOperation *operation, id response) {
                 NSLog(@"JSON! %@", response);
             }
             failure:^(AFHTTPRequestOperation *operation, NSError *error) {
             }];

Here's a trick that I discovered as well. In the NSError object you can parse it and retrieve the error message (if the HTTP response had a JSON error message):

failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSDictionary *JSON =
    [NSJSONSerialization JSONObjectWithData: [error.localizedRecoverySuggestion dataUsingEncoding:NSUTF8StringEncoding]
                                    options: NSJSONReadingMutableContainers
                                      error:nil];
           failureCallback(JSON[@"message"]);
}
like image 190
Andrew Avatar answered Dec 26 '22 17:12

Andrew


Try this ... I think there maybe something wrong with your client settings.

NSMutableURLRequest *request = [client requestWithMethod:@"POST" path:@"/app/open_connection/" parameters:params];

AFJSONRequestOperation *operation =
[AFJSONRequestOperation JSONRequestOperationWithRequest:request 
    success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        NSLog(@"successful login! %@", [JSON valueForKeyPath:@"status"]);
    }
    failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
        NSLog(@"error opening connection");
        NSAlert *alert = [NSAlert alertWithError:error];
        [alert runModal];
}];
[operation start];
like image 41
HazA Avatar answered Dec 26 '22 18:12

HazA