SebT
SebT

Reputation: 45

AFNetworking, sending an NSDictionary inside an NSDictionary

I'm trying to send a nested dictionary to my server using AFNetworking.

The dictionary follows this quite simple pattern :

NSMutableDictionary *dico1 = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                             @"value1", @"key1",
                             @"value2", @"key2",
                             @"value3", @"key3",
                             @"value4", @"key4",
                             nil];

NSMutableDictionary *dico2 = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                             @"value1", @"key1",
                             dico1,     @"key2",
                             @"value3", @"key3",
                             @"value4", @"key4",
                             nil];


When I send dico2 to my server with "the good old couple" NSJSONSerialization/NSURLConnection, the server receives what I expect, meaning (here the log trace) :

parameters =
 { key2: { key2: 'value2', key3: 'value3', key1: 'value1', key4: 'value4' },
   key3: 'value3',
   key1: 'value1',
   key4: 'value4' }

My server is written in javascript and checks the existence of parameters.key2. In this case, parameters.key2 is defined, so server can work with it without problem. This is the way I always did and it worked perfectly...

But now, I'm trying to send exactly the same dico2 with AFJSONRequestOperation (with [httpClient setParameterEncoding:AFJSONParameterEncoding]) and I receive the following :

parameters =
{ key1: 'value1',
  'key2[key1]': 'value1',
  'key2[key2]': 'value2',
  'key2[key3]': 'value3',
  'key2[key4]': 'value4',
  key3: 'value3',
  key4: 'value4' }

And my server sends an error saying that parameters.key2 is undefined !

It seems like JSON data are not encoded the same way between NSJSONSerialization/NSURLConnection and AFJSONRequestOperation.

How can I obtain the same encoding than before with AFJSONRequestOperation ?
Is there someone who could help on this ?

Thanks !


EDIT FOR MATTT:

Here is how I use AFHTTPClient : I factorized httpClient into a common method I use everywhere in my code :

-(NSMutableURLRequest*)formatAFJSONRequest:(NSString*)type command:(NSString*)command parameters:(NSMutableDictionary*)parameters {


NSURL *api_url = [NSURL URLWithString:[NSString stringWithFormat:ADDRESS, API_KEY]];

AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:api_url];
[httpClient setParameterEncoding:AFJSONParameterEncoding];

NSMutableURLRequest *JSONRequest = [httpClient requestWithMethod:@"GET"
                                                            path:[NSString stringWithFormat:@"%@/%@", type, command]
                                                      parameters:parameters];

JSONRequest.cachePolicy     = CACHE_POLICY_SERVER_REQUEST;
JSONRequest.timeoutInterval = TIMEOUT_SERVER_REQUEST;   

if (DEBUG_1) { NSLog(@"[%@/%@] sent to server (AFN): %@", type, command, parameters); }

return JSONRequest;
}

Thanks so much for your help!

Seb

Upvotes: 0

Views: 918

Answers (1)

mattt
mattt

Reputation: 19544

GET requests don't have HTTP bodies, so parameters are encoded as query strings. If you really need the request to be a GET the work around would be to create a POST request first and then change the method to GET.

This is explained in AFNetworking's docs for AFHTTPClient -parameterEncoding:

The AFHTTPClientParameterEncoding value corresponding to how parameters are encoded into a request body for request methods other than GET, HEAD or DELETE. This is AFFormURLParameterEncoding by default.

Warning: Some nested parameter structures, such as a keyed array of hashes containing inconsistent keys (i.e. @{@"": @[@{@"a" : @(1)}, @{@"b" : @(2)}]}), cannot be unambiguously represented in query strings. It is strongly recommended that an unambiguous encoding, such as AFJSONParameterEncoding, is used when posting complicated or nondeterministic parameter structures.

Upvotes: 1

Related Questions