AFNetworking send array in JSON parameters of post request
Asked Answered
E

1

6

I'm trying to send parameters to my server via POST, and it works generally, but I can't figure out how to send JSON that contains an array as one of the parameters. Here's what I've tried:

AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:myURL]];
NSMutableArray *objectsInCart = [NSMutableArray arrayWithCapacity:[_cart count]];
for(NSDictionary *dict in _cart)
{
    NSObject *object = [dict objectForKey:@"object"];
    NSDictionary *objectDict = @{@"product_id": [NSString stringWithFormat:@"%d",[object productID]],
                                 @"quantity": [NSString stringWithFormat:@"%d", [[dict objectForKey:@"count"] intValue]],
                                 @"store_id": [NSString stringWithFormat:@"%d", [Store getStoreID]],
                                 @"price": [NSString stringWithFormat:@"%.2f", [object price]]};
    [objectsInCart addObject:objectDict];
}
NSError *error = nil;
NSString *cartJSON = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:objectsInCart
                                                                                    options:NSJSONWritingPrettyPrinted
                                                                                      error:&error]
                                           encoding:NSUTF8StringEncoding];

if(error)
{
    NSLog(@"Error serializing cart to JSON: %@", [error description]);
    return;
}

NSDictionary *parameters = @{@"status": @"SUBMITTED",
                             @"orders": cartJSON};

NSMutableURLRequest *orderRequest = [httpClient requestWithMethod:@"POST"
                                                             path:@"/app/carts"
                                                       parameters:parameters];

AFJSONRequestOperation *JSONOperation = [[AFJSONRequestOperation alloc] initWithRequest:orderRequest];

However, I get an error when sending this JSON. Any suggestions are much appreciated!

Ecstatic answered 20/8, 2013 at 18:8 Comment(4)
I don't know what the server expects, but usually, every item in JSON has a key, including the array. You're just sending the array now, without a key for it. Try `NSString *cartJSON = @"'products':%@", [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:objectsInCart options:NSJSONWritingPrettyPrinted error:&error] encoding:NSUTF8StringEncoding];Keldon
If you look at the parameters dictionary, the key for the array is @"orders"Ecstatic
ok, my bad I missed that. Did you look at the actual data being sent over the line? I've come to value an app like Charles proxy very much to intercept all traffic from my app to external servers.Keldon
For a future reference to others who are using AFNetworking 2.xx, you don't have to serialize any array or dictionary to JSON, just pass them to your AFHTTPRequestOperationManager as they are, and AFNetworking will handle all the things.But do not forget adding manager.requestSerializer = [AFJSONRequestSerializer serializer]; as mentioned in the accepted answer.Kingfisher
A
9

I don't see where you're specifying you want to post JSON, so I'm betting you're sending Form URL Parameter Encoding, which goes like this, according to the AFHTTPClient documentation:

If a query string pair has a an NSArray for its value, each member of the array will be represented in the format field[]=value1&field[]=value2. Otherwise, the pair will be formatted as "field=value". String representations of both keys and values are derived using the -description method. The constructed query string does not include the ? character used to delimit the query component.

If your server is indeed expecting you to post JSON, add this on the second line to tell AFNetworking that:

// AFNetworking 1.0
// httpClient is a subclass of AFHTTPClient
httpClient.parameterEncoding = AFJSONParameterEncoding;

// AFNetworking 2.0
// httpClient is a subclass of AFHTTPRequestOperationManager or AFHTTPSessionManager
httpClient.requestSerializer = AFJSONRequestSerializer;

You would then remove your call to NSJSONSerialization and just put objectsInCart into the parameters dictionary.

A side note: it's normal to subclass AFHTTPRequestOperationManager or AFHTTPSessionManager (AFNetworking 2.0) or AFHTTPClient (AFNetworking 1.0) and put this type of configuration in your initWithBaseURL: method. (You probably don't want to spin up a new client for every request.)

Agrippina answered 21/8, 2013 at 1:0 Comment(1)
Gah yeah I found this earlier, should have updated the post. Thanks!Ecstatic

© 2022 - 2024 — McMap. All rights reserved.