13

I've setup a JSON post with AFNetworking in Objective-C and am sending data to a server with the following code:

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

I'm receiving information through the same request, and want to send the data to a NSString. How would I go about doing that with AFNetworking?

James
  • 717
  • 2
  • 6
  • 9
  • 4
    I think you've got "Content-Type" and "application/json" reversed in our setValue:forHTTPHeaderField call – Colin Jul 29 '14 at 22:00

4 Answers4

29

responseObject is either an NSArray or NSDictionary. You can check at runtime using 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 */
}

If you really need the string of the JSON, it's available by looking at operation.responseString.

Aaron Brager
  • 65,323
  • 19
  • 161
  • 287
7

In this case, when the web service responds with JSON, the AFNetworking will do the serialization for you and the responseObject will most likely be either a NSArray or NSDictionary object.

Such an object should be more useful for you than string with JSON content.

Rafał Sroka
  • 39,540
  • 23
  • 113
  • 143
  • 1
    Hey - AFNetworking already provides the string in `responseObject.responseString`. Your answer would work, but there's no need to parse the NSData object again :) – Aaron Brager Feb 23 '14 at 00:21
  • Hey @Aaron, thanks for pointing it out, silly me. I need to finally get some sleep :) – Rafał Sroka Feb 23 '14 at 00:27
  • 1
    Man, I was so stupid. Maybe it's a beer, maybe the fact that I am primarily an Android dev, but thanks. – Dimmy3 Jan 20 '15 at 21:37
6

In my case, it's looks like (maybe it can helps)

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

Also would be great to check type of response object (like https://stackoverflow.com/a/21962445/3628317 answer)

Community
  • 1
  • 1
levo4ka
  • 2,248
  • 1
  • 19
  • 32
1

I find it works best to subclass AFHTTPClient like so:

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

The important bits are:

  • Setting the 'Accept' in such a way that AFJSONRequestOperation becomes eligible.
  • Adding AFJSONRequestOperation to the http operation classes.

Then you can use it like so:

#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

The beauty of this is that your responseObject is automatically JSON-parsed into a dictionary (or array) for you. Very clean.

(this is for afnetworking 1.x)

Chris
  • 39,719
  • 45
  • 189
  • 235