AFNetworking 将 JSON 数组发布为多个单条目字典

Posted

技术标签:

【中文标题】AFNetworking 将 JSON 数组发布为多个单条目字典【英文标题】:AFNetworking posts JSON arrays as multiple single-entry dictionaries 【发布时间】:2014-01-24 23:51:32 【问题描述】:

我遇到了与here 讨论的问题类似的问题。

我正在尝试将 JSON 发布到服务器。

这是应该工作但不能工作的Objective-C代码。我在响应对象中得到一个空数组,不知道为什么:

    AFHTTPRequestOperation * operation = [manager POST:uploadScriptUrl
      parameters:mutableJSON
      success:^(AFHTTPRequestOperation * operation, id responseObject) 
          successBlock(operation, responseObject);
      
      failure:^(AFHTTPRequestOperation * operation, NSError * error) 
          failureBlock(operation, error);
      ];

这段代码(改编自我用来上传图片的代码)KIND OF 有效。我知道这绝对不是经过批准的方法:

    AFHTTPRequestOperationManager * manager = [AFHTTPRequestOperationManager manager];
    AFJSONRequestSerializer * requestSerializer = [AFJSONRequestSerializer serializer];
    [requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    manager.requestSerializer = requestSerializer;

    AFHTTPRequestOperation * operation = [manager POST:uploadScriptUrl
    parameters:mutableJSON //passed in
    constructingBodyWithBlock:^(id <AFMultipartFormData> formData) 
        //Do nothing
   
    success:^(AFHTTPRequestOperation * operation, id responseObject) 
        successBlock(operation, responseObject);
    
    failure:^(AFHTTPRequestOperation * operation, NSError * error) 
        failureBlock(operation, error);
    ];

它将我的 JSON 发布到服务器,但在制定请求的过程中,JSON 被破坏了。

它是这样开始的:


"key1": [
    
        "dictionary1": 
            "param1": "value1",
            "param2": "value2",
            "array1A": [
                "value1",
                "value2"
            ],
            "array1B": [
                "value1",
                "value2"
            ]
        
    
]

这是 AFNetworking 发送到服务器的内容:


"key1": [
    
        "dictionary1": 
            "array1A": [
                "value1"
            ]
        
    ,
    
        "dictionary1": 
            "array1A": [
                "value2"
            ]
        
    ,
    
        "dictionary1": 
            "array1B": [
                "value1"
            ]
        
    ,
    
        "dictionary1": 
            "array1B": [
                "value2"
            ]
        
    ,
    
        "dictionary1": 
            "param1": "value1"
        
    ,
    
        "dictionary1": 
            "param2": "value2"
        
    
]

这是 Charles 为请求显示的内容。在服务器接触数据之前,您可以看到请求中的 JSON 结构已经发生了怎样的变化。

这是我在服务器上使用的 php。现在很简单:

<?php

header('Content-type: application/json'); //Not sure if this is needed.

$json_string = json_encode($_POST);

header("HTTP/1.0 200 OK");
echo $json_string;

?>

所以,说了这么多,下面是我的问题:

    AFNetworking 是否处理嵌套的 JSON 数组?在this page Mattt 上说:“你所描述的结构不能用查询字符串编码来确定地表示。”我正在使用 POST,因此不涉及查询字符串。但也许 POST 数据也存在限制?

    我也很好奇为什么包含constructingBodyWithBlock 的较长的AFNetworking 调用成功而较短的调用失败。但是,这个答案对我来说不太重要。较长的方法几乎可以工作,如果它返回与我发送的相同 JSON,我会很乐意使用它。

谢谢大家!

【问题讨论】:

【参考方案1】:

我使用的是 POST,因此不涉及查询字符串。但也许 POST 数据也存在限制?

限制不在于 POST,它是 URL 表单编码。我继续说你应该编码为 JSON,你可以通过对你的经理进行以下配置更改来做到这一点:

manager.requestSerializer = [AFJSONRequestSerializer serializer];.

另外,除非您实际上是在构建多部分请求,否则不要使用该方法的 constructingBodyWithBlock 版本。

【讨论】:

我已经这样做了,但没有在帖子中包含它。应该有,但帖子似乎很长。我已经编辑了原始帖子以包含它。感谢您澄清限制以及它们的来源。那么,我将如何上传我选择的任何复杂程度的 JSON?【参考方案2】:

我刚刚处理了同样的问题,我能找到的唯一解决方案是从数组中创建一个字典。一定有更好的办法,这太丑了……

    NSMutableDictionary *arrayDict = [[NSMutableDictionary alloc] init];
    int counter = 0;
    for (NSMutableDictionary *arrayItem in arrayToSend) 
        [arrayDict setObject:arrayItem forKey:[NSNumber numberWithInt:counter]];
        counter++;
    

否则一切都会变得扁平化。我使用 AFJSONRequestSerializer,但这似乎无关紧要。

【讨论】:

这是在 url 查询中必须发送数据时获取编码的最简单方法【参考方案3】:

丑陋的解决方案是为弱者准备的: How can I POST an NSArray of NSDictionaries inside an NSDictionary without problems?

这篇文章的答案包含了你所需要的一切。

【讨论】:

【参考方案4】:

我最近也遇到了这个问题,我有以下参数要发送到服务器,但是“功能”数组被分成 4 个部分,而不仅仅是 2 个字典。

         "description": "Temporary Description",   
          "name": "Product Name",  
          "feature": [
            
              "fkey": "FT1",
              "fvalue": "FD1"
            ,
            
              "fkey": "FT2",
              "fvalue": "FD2"
               
         ] 
    

所以我改了

AFURLRequestSerialisation.m

AFQueryStringPairsFromKeyAndValue(NSString *key, id value)方法中替换了这一行

[mutableQueryStringComponents addObjectsFromArray:AFQueryStringPairsFromKeyAndValue([NSString stringWithFormat:@"%@[]", key], nestedValue)];

[mutableQueryStringComponents addObjectsFromArray:AFQueryStringPairsFromKeyAndValue([NSString stringWithFormat:@"%@[%i]", key, [array indexOfObject:nestedValue]], nestedValue)];

这就成功了。我希望这可能对某人有所帮助。

【讨论】:

以上是关于AFNetworking 将 JSON 数组发布为多个单条目字典的主要内容,如果未能解决你的问题,请参考以下文章

以 JSON 字符串数组形式获取 AFNetworking 响应的结果

AFNetworking 1.x 将 JSON 发布到 PHP

AFNetworking 2.0 将 [] 方括号添加到发送到服务器的 json

JSON 文本没有以数组开头 AFNetworking 错误

使用 AFNetworking 将 JSON 解析为 NSDictionary

使用 AFNetworking 2.5 将 JSON 序列化为 NSArray