Search code examples
jsonswiftalamofire

How to POST a nested JSON using Alamofire?


I want to use Alamofire(V3.5.1), and I am using Swift(V2.3). the JSON I want to post is this.

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

And I try to make the Alamofire parameters like this

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

But the result I get is this. FAILURE: Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0.

Q1:How can I POST a correct nested json in the body?

EDIT:I tried to use @Zonily Jame's way to create the JSON Object, but it failed. Here's my code:

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

and I printed the parameters variable which looked like this:

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

Somehow the syntax is still incorrect. And I also tried to use dictToJSON() on the variable configureData, I still got the same result.


The expected response should be

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

EDIT: This is the API's document about how to phrase response but in JAVA

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();
        }

and request code

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();

NOTE:imgBase64is a String.

Q2:How can I analyse this kind of JSON? I just want the dataValue,Thanks


Solution

  • What you should do is to first convert your Dictionaries/Arrays inside your Super Dictionary to a JSON object

    For example let's make an object

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

    For this to work we need to separate these objects, which would roughly look like this (just did this for readability)

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

    And then just convert them to a JSON Object by using NSJSONSerialization by using these functions

    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"])
        ])
    ]
    

    You can now use this object in your Alamofire Request