netshark1000
netshark1000

Reputation: 7403

Alamofire: Send JSON with Array of Dictionaries

I have a data structure that looks like this in JSON:

[{
    "value": "1",
    "optionId": "be69fa23-6eca-4e1b-8c78-c01daaa43c88"
}, {
    "value": "0",
    "optionId": "f75da6a9-a34c-4ff6-8070-0d27792073df"
}]

Basically it is an array of dictionaries. I would prefer to use the default Alamofire methods and would not like to build the request manually. Is there a way to give Alamofire my parameters and Alamofire does the rest?

If I create everything by hand I get an error from the server that the send data would not be correct.

    var parameters = [[String:AnyObject]]()

    for votingOption in votingOptions{

        let type = votingOption.votingHeaders.first?.type

        let parameter = ["optionId":votingOption.optionID,
            "value": votingOption.votingBoolValue
        ]
        parameters.append(parameter)
    }

    let jsonData = try! NSJSONSerialization.dataWithJSONObject(parameters, options: [])
    let json = try! NSJSONSerialization.JSONObjectWithData(jsonData, options: .AllowFragments)


    if let url = NSURL(string:"myprivateurl"){
        let request = NSMutableURLRequest(URL: url)
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.HTTPMethod = Method.POST.rawValue
        request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(parameters, options: [])

        AlamofireManager.Configured.request(request)
            .responseJSON { response in
           //Handle result     
        }
    }

Upvotes: 8

Views: 12745

Answers (3)

jorgifumi
jorgifumi

Reputation: 195

I have the same issue and resolved this way:

I created a new struct implementing the Alamofire's ParameterEncoding protocol:

struct JSONArrayEncoding: ParameterEncoding {
    private let array: [Parameters]

    init(array: [Parameters]) {
        self.array = array
    }

    func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
        var urlRequest = try urlRequest.asURLRequest()

        let data = try JSONSerialization.data(withJSONObject: array, options: [])

        if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {
            urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
        }

        urlRequest.httpBody = data

        return urlRequest
    }
}

Then, I can do this:

let parameters : [Parameters] = bodies.map( { $0.bodyDictionary() })
Alamofire.request(url, method: .post, encoding: JSONArrayEncoding(array: parameters), headers: headers).responseArray { ... }

It worked for me. Hope can help someone else.

Upvotes: 17

boidkan
boidkan

Reputation: 4731

You can do something like this:

Alamofire.request(.POST, urlPath, parameters: params).responseJSON{ request, response, data in
    //YOUR_CODE
}

Where parameters is [String:AnyObject] and yes Alamofire takes care of the rest.

Since it looks like you are using a manager you can do this

YOUR_ALAMOFIRE_MANAGER.request(.POST, url, parameters: params).responseJSON{ request, response, JSON in
   //enter code here
}

Here is the source code:

public func request(
    method: Method,
    _ URLString: URLStringConvertible,
    parameters: [String: AnyObject]? = nil,
    encoding: ParameterEncoding = .URL,
    headers: [String: String]? = nil)
    -> Request
{
    let mutableURLRequest = URLRequest(method, URLString, headers: headers)
    let encodedURLRequest = encoding.encode(mutableURLRequest, parameters: parameters).0
    return request(encodedURLRequest)
}

EDIT:

Since your data is currently [[String:AnyObject]] you will need to modify it so it is in the form [String:AnyObject]. One way you could do this i by doing this ["data":[[String:AnyObject]]]. You will probably have to change your api end point though.

Upvotes: -2

ogres
ogres

Reputation: 3690

You can provide parameter encoding for JSON POST request and it will send the data as JSON in request body.

Alamofire.request(.POST, "https://httpbin.org/post", parameters: parameters, encoding: .JSON)

This is described in the ReadMe file of Alamofire github - https://github.com/Alamofire/Alamofire#post-request-with-json-encoded-parameters

let parameters = [
    "foo": [1,2,3],
    "bar": [
        "baz": "qux"
    ]
]

Alamofire.request(.POST, "https://httpbin.org/post", parameters: parameters, encoding: .JSON)
// HTTP body: {"foo": [1, 2, 3], "bar": {"baz": "qux"}}

Upvotes: -2

Related Questions