[Answered ]-Nested Json with multipart/form-data in AFNetworking 2.x

1đź‘Ť

constructingBodyWithBlock is overriding your AFJSONRequestSerializer and your dictionary is encoded as form data. There is no way to have two content types (multipart/form-data and application/json) for a request at the same time, so you’ll have to do this another way.

One possibility is to encode the JSON as an NSData object and append it to the multipart form along with the image data:

NSError *error = nil;
NSData *paramData = [NSJSONSerialization dataWithJSONObject:params
                                                   options:0
                                                     error:&error];
[formData appendPartWithFileData:paramData
          name:@"params"
          filename:@"params"
          mimeType:@"application/json"]

You can access the serialized parameters through request.FILES['params']. Despite the mime-type, I doubt that django will automatically parse the JSON data into a dictionary, but you could do that manually with json.loads.

👤gbs

1đź‘Ť

In AFNetworking3.0, you can introduce JSON in a form using the appendPartWithFormData function

[formData appendPartWithFormData:params name:@"params"];

On the server side, you can access the serialized data using json.loads() on the object. Here is a full snippet from some code I wrote:

AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST"
                                                                                          URLString:requestUrl parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
    [formData appendPartWithFormData:[self dictToJson:params] name:@"params"];
    [formData appendPartWithFileData:fileData name:fileGeneralName fileName:fileName mimeType:mimeType];
} error:nil];
[[manager uploadTaskWithStreamedRequest:request progress:nil completionHandler:^(NSURLResponse* response, id responseObject, NSError* error) {
    [self callCompletionBlock:responseObject withError:error withResponse:response completionHandler:completionBlock];
}] resume];

There’s a serialization function in that snippet, which I’ll also paste for completion:

+(NSData*)dictToJson:(NSDictionary*)dict {
NSError* error = nil;
return [NSJSONSerialization dataWithJSONObject:dict options:0 error:&error]; }
👤ShayakB

Leave a comment