如何使用 Alamofire 发布嵌套的 JSON?

Posted

技术标签:

【中文标题】如何使用 Alamofire 发布嵌套的 JSON?【英文标题】:How to POST a nested JSON using Alamofire? 【发布时间】:2016-12-08 07:35:02 【问题描述】:

我想使用 Alamofire(V3.5.1),我正在使用 Swift(V2.3)。我要发布的 JSON 是这样的。


  "inputs": [
    
      "image": 
        "dataType": 50,
        "dataValue": "base64_image_string"
      ,
      "configure": 
        "dataType": 50,
        "dataValue": "\"side\":\"face\""
      
    
  ]

我尝试使Alamofire 参数像这样

    let parameters : [String: AnyObject] = [
        "inputs" : [
        [ "image":[
            "dataType":50,
            "dataValue":(base64String)
            ],
            "configure":[
            "dataTpye":50,
                "dataValue": ["side" :"face"]
            ]
            ]
        ]
    ]

但我得到的结果是这样的。 FAILURE: Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0.

Q1:如何在正文中发布正确的嵌套 json?

编辑:我尝试使用@Zonily Jame 的方式创建 JSON 对象,但失败了。这是我的代码:

        let imageData:[String:AnyObject] = ["dataType":50, "dataValue":"string"]
    let configureData:[String:AnyObject] = ["dataType":50, "dataValue":"\"side\":\"face\""]
    let inputsData:[String:AnyObject] = ["image":dictToJSON(imageData) , "configure":dictToJSON(configureData)]
    let parameters:[String:AnyObject] = ["inputs":dictToJSON(inputsData)]

我打印了parameters 变量,看起来像这样:

["inputs": 
    configure =     
        dataType = 50;
        dataValue =         
            side = face;
        ;
    ;
    image =     
        dataType = 50;
        dataValue = "";
    ;
]

不知何故,语法仍然不正确。而且我还尝试在变量configureData 上使用dictToJSON(),我仍然得到相同的结果。


预期的反应应该是

  
  "outputs": [
    
      "outputLabel": "ocr_id",
      "outputMulti": ,
      "outputValue": 
        "dataType": 50,
        "dataValue": "\"address\": \"string\", \"config_str\" : \"\"side\":\"face\"\", \"name\" : \"Jack\",\"num\" : \"1234567890\", \"success\" : true"
      
    
  ]

编辑:这是关于如何在 JAVA 中使用短语响应的 API 文档

try 
            JSONObject resultObj = new JSONObject(result);
            JSONArray outputArray = resultObj.getJSONArray("outputs");
            String output = outputArray.getJSONObject(0).getJSONObject("outputValue").getString("dataValue"); 
            JSONObject out = new JSONObject(output);
            if (out.getBoolean("success")) 
                String addr = out.getString("address"); 
                String name = out.getString("name"); 
                String num = out.getString("num"); 
                System.out.printf(" name : %s \n num : %s\n address : %s\n", name, num, addr);
             else 
                System.out.println("predict error");
            
         catch (JSONException e) 
            e.printStackTrace();
        

和请求代码

public static JSONObject getParam(int type, JSONObject dataValue) 
        JSONObject obj = new JSONObject();
        try 
            obj.put("dataType", type);
            obj.put("dataValue", dataValue);
         catch (JSONException e) 
            e.printStackTrace();
        
        return obj;
    


    public static JSONObject getParam(int type, String dataValue) 
        JSONObject obj = new JSONObject();
        try 
            obj.put("dataType", type);
            obj.put("dataValue", dataValue);
         catch (JSONException e) 
            e.printStackTrace();
        
        return obj;
    

        JSONObject requestObj = new JSONObject();
        try 
            JSONObject configObj = new JSONObject();
            JSONObject obj = new JSONObject();
            JSONArray inputArray = new JSONArray();
            configObj.put("side", configStr);
            obj.put("image", getParam(50, imgBase64));
            obj.put("configure", getParam(50, configObj.toString()));
            inputArray.put(obj);
            requestObj.put("inputs", inputArray);
         catch (JSONException e) 
            e.printStackTrace();
        
        String body = requestObj.toString();

注意:imgBase64是一个字符串。

Q2:如何分析这种JSON?我只想要dataValue,谢谢

【问题讨论】:

您可以发布您的 Alamofire 代码吗? 注意:必要时可以隐藏网址 你得到的参数是正确的imo,在你的api中你确定服务器接受application/json类型的参数吗?我不明白你在“我希望得到回应”之后的意思,你能改述一下吗? @ZonilyJame 我的意思是服务器会给我这个响应,这是 API 文档中的一个正确示例。我使用这个 Alamofire 方法`Alamofire.request(.POST, url, parameters: parameters,编码:.JSON,标头:标头).responseJSON ` 我没有更多的swift代码,只需将'dataValue'更改为字符串 非常感谢 【参考方案1】:

您可以提供嵌套字典的字典类型,也可以为需要字典的每个键创建单独的字典。 像 [AnyObject: AnyObject] 。

对于键的分析,您可以将响应转换为字典形式并使用其方法 valueforKeyPath

【讨论】:

但是Alamofire.request需要一个参数作为[String:AnyObject],所以我不能把我的身体作为[AnyObject:AnyObject]。我知道如何分析一个普通的json,但我不知道如何分析嵌套 json 像 "dataValue": "\"address\": \"string\", \"config_str\" : \"\"side\":\"face\"\", \"name\" : \"Jack\",\"num\" : \"1234567890\", \"success\" : true" 你能帮帮我吗? 如果让 jsonResult = 响应为? NSDictionary let OrderObjectIds = jsonResult.value(forKeyPath: "result.objectId") 在 keyPath 中使用“outputs.outputValue.dataValue” 您可以使用 [AnyObject:AnyObject] 作为图像和配置字典 让参数:[String:AnyObject] = ["className": ApiConstants.KClassOrder,"include":["medicine","_User"] ,"data":data]。和数据字典一样。 var data : [[String:AnyObject]] = [ [ "column" : "user" as AnyObject, "value" : userObjectId as AnyObject,"class" : "_User" as AnyObject]]【参考方案2】:

您应该首先将Dictionaries/Arrays 中的Super Dictionary 转换为JSON 对象

例如,让我们制作一个对象

let object = [
    "franchise": [
        "name": "Marvel",
        "movies": ["Doctor Strange", "Iron Man", "Spider Man"]
    ]
]

为此,我们需要分离这些对象,大致如下所示(只是为了可读性而这样做)

let movies:[String] = ["Doctor Strange", "Iron Man", "Spider Man"]

let franchiseDetails:[String:AnyObject] = [
  "name": "Marvel",
    "movies": movies
]
let franchise:[String:AnyObject] = [
    "franchise": franchiseDetails
]

然后使用NSJSONSerialization 使用这些函数将它们转换为 JSON 对象

func dictToJSON(dict:[String: AnyObject]) -> AnyObject 
    let jsonData = try! NSJSONSerialization.dataWithJSONObject(dict, options: .PrettyPrinted)
    let decoded = try! NSJSONSerialization.JSONObjectWithData(jsonData, options: [])
    return decoded


func arrayToJSON(array:[String]) -> AnyObject 
    let jsonData = try! NSJSONSerialization.dataWithJSONObject(array, options: .PrettyPrinted)
    let decoded = try! NSJSONSerialization.JSONObjectWithData(jsonData, options: [])
    return decoded



let newObject = [
    "franchise": dictToJSON([
        "name": "Marvel",
        "movies": arrayToJSON(["Doctor Strange", "Iron Man", "Spider Man"])
    ])
]

你现在可以在你的 Alamofire 请求中使用这个对象

【讨论】:

感谢您的回答,非常有用。我还有一个问题是如何将此字符串添加到字典中? "dataValue": "\"side\":\"face\"" 我很困惑。 那应该是字典中的字典吗? 我不确定。这是一个 API 请求示例 我感觉这是Dictionary 中的Dictionary。基本上你应该做的是将内部 Dictionary 转换为 JSON 对象,就像我在回答中所做的那样。所以它看起来像这样 ["dataValue": dictToJSON(["side":"face"])] 这是因为 Alamofire 接受 [String: AnyObject],这是一个 Dictionary 参数值

以上是关于如何使用 Alamofire 发布嵌套的 JSON?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 objectMapper 和 Alamofire 发布嵌套的 json?

json 使用 alamofire 快速发布嵌套对象

iOS swift Codable 不能与 Alamofire 一起使用 JSON 嵌套数据?

使用 Alamofire 在 Swift 中发布嵌套 JSON

使用 URLRequestConvertible 协议将 JSON 嵌套为请求参数 (Alamofire)

Alamofire 嵌套 JSON 序列化器