在AFNetworking 2.x中嵌套了具有multipart / form-data的Json

时间:2015-10-20 10:10:20

标签: ios objective-c django afnetworking-2

我正在尝试使用AFNetworking库从我的ios应用程序发送带有图像的嵌套json。我能够成功发送json数据和图像,但在服务器中json结构的变化是不同的。

我的应用内的HTTP请求: -

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSDictionary *params = @{@"requestData":@{@"username":@"200OK",@"password":@"password"}};

manager.requestSerializer = [AFJSONRequestSerializer serializer];
manager.responseSerializer = [AFJSONResponseSerializer serializer];


[manager POST:Self_URL
   parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
           [formData appendPartWithFileData:UIImagePNGRepresentation(image)
                                       name:@"file"
                                   fileName:@"file"
                                   mimeType:@"image/jpeg"];

} success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"Response: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}]; 

所以在我的django服务器中,我期待params作为字典与params相同,但request.POST即将来临

content_type---> multipart/form-data; boundary=Boundary+247685AB6DF2B3BA
<QueryDict: {'requestData[password]': [u'password'], 'requestData[username]': [u'200OK']}>

如何发送json数据以便从服务器轻松访问? 我遗失的任何东西或出了什么问题?

2 个答案:

答案 0 :(得分:1)

constructingBodyWithBlock会覆盖您的AFJSONRequestSerializer,您的字典会被编码为表单数据。同时,请求无法为请求提供两种内容类型(multipart/form-dataapplication/json),因此您必须采用另一种方式执行此操作。

一种可能性是将JSON编码为NSData对象,并将其与图像数据一起附加到多部分表单:

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

您可以通过request.FILES['params']访问序列化参数。尽管有mime类型,我怀疑django会自动将JSON数据解析为字典,但你可以用json.loads手动完成。

答案 1 :(得分:1)

在AFNetworking3.0中,您可以使用appendPartWithFormData函数

在表单中引入JSON
[formData appendPartWithFormData:params name:@"params"];

在服务器端,您可以使用对象上的json.loads()访问序列化数据。以下是我写的一些代码的完整摘录:

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

该片段中有一个序列化功能,我也会将其粘贴完成:

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