Alamofire: Send JSON with Array of Dictionaries

Alamofire: Send JSON with Array of Dictionaries

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.

Sending array of dictionaries with alamofire

The problem was in append method. I have coded on PHP 5 years and forgoted that in Swift the indexes not automatically assigned like in PHP. So, my first bugged code was:

func getParameters() -> [[String: AnyObject]] {
var result = [[String: AnyObject]]()

for mmap in mmaps {
let material: [String: AnyObject] = [
"material_id": mmap.material.id,
"quantity": mmap.qty
]
result.append(material)
}

return result
}

The answer is hard assign the keys as you need:

func getParameters() -> [String: [String: AnyObject]] {
var result = [String: [String: AnyObject]]()

let mmaps = self.mmaps.allObjects as [Mmap]
for i in 0..<mmaps.count {
let mmap = mmaps[i]
let material: [String: AnyObject] = [
"material_id": mmap.material.id,
"quantity": mmap.qty
]
result["\(i)"] = material
}

return result
}

How to post an array of dictionary (json object), in swift using alamofire?

Alamofile Parameters object is of type [String: Any], which is not what you want.
Instead make an array of multiple dictionaries and pass that to this function :

func uploadDataToServer(endPoint: String, dataToUpload: [[String: Any]], completionHandler:@escaping (Bool) -> ()){

let url = Config.BASE_URL + endPoint

var request = URLRequest(url: URL.init(string: url)!)
request.httpMethod = "POST"

request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let dataToSync = dataToUpload
request.httpBody = try! JSONSerialization.data(withJSONObject: dataToSync)

Alamofire.request(request).responseJSON{ (response) in

print("Success: \(response)")
switch response.result{
case .success:
let statusCode: Int = (response.response?.statusCode)!
switch statusCode{
case 200:
completionHandler(true)
break
default:
completionHandler(false)
break
}
break
case .failure:
completionHandler(false)
break
}
}
}

Your array should be :

var uploadArray = [[String: Any]]()
let ordersDictionary = [
"custid" : defaults.object(forKey: "userid")!,
"carttotal" : Int(totalPrice),
"cartitems" : ordersArray,
"deliverytime" : timeSlot,
"custaddress" : custAdd!,
"areacode" : defaults.object(forKey: "areaCode")!
]

uploadArray.append(ordersDictionary)

Then pass uploadArray to above function.

Send put request with array of dictionaries with Alamofire

Update: The major issue here is that you're not formatting your JSON properly, Here is what you need to do:

struct Item: Codable {
let name: String
let price: Float
}
struct User: Codable {
let username: String
let fullName: String

enum CodingKeys: String, CodingKey {
case username
case fullName = "full_name"
}
}
struct Parameter: Codable {
let user: User
let item: Item
}
let item = Item(name: "pen", price: 0)
let user = User(username: "Dave", fullName: "Dave Grohl")
let parameter = Parameter(user: user, item: item)

let data = try! JSONEncoder().encode(parameter)

var request = URLRequest(url: url)
request.httpMethod = "PUT"
request.httpBody = data
AF.request(request).response { (response) in
debugPrint(response)
//...
}

Previous Answer: It's because your parameters have a mismatch in User. You can fix it by just modifying the User struct as follows:

struct User: Codable {
let username: String
let fullName: String

enum CodingKeys: String, CodingKey {
case username
case fullName = "full_name"
}
}

An alternate approach is to use a custom JSONDecoder and set it's keyEncodingStrategy to convertToSnakeCase, like this:

let user = User(username: "Dave", fullName: "Dave Grohl")
let decoder = JSONEncoder()
decoder.keyEncodingStrategy = .convertToSnakeCase
let userData = try! decoder.encode(user)
let userString = String(data: userData, encoding: .utf8)!

Note: Usually the JSON format contains both snake-case and camel-case and hence using the first approach is the better choice in my opinion. But both would work.

post JSON object with a dictionary and an array of dictionaries using alamofire

Ok I've solved by maping the simulated goods array and converting it to a dictionary, like so:

class SimulationsRepository: BaseRepository {

init() {
super.init(url: "/Simulations")
super.BaseUrl = "http://0.0.0.0:3000/api"
}

func confirmSimulation(simulation: Simulation, goods: [SimulatedGoods], then: @escaping ThenBlock) {
let goodsDict = goods.map { (simulatedGoods) -> [String: Any] in
return simulatedGoods.toDictionary()
}
let sim = simulation.toDictionary()

let params: [String: Any] = [
"simulation": sim,
"goods": goodsDict
]
super.customPost("/confirm", parameters: params, then: then)
}

}

By the way, I got the idea for maping the array like this from the book: https://www.hackingwithswift.com/store/pro-swift



Related Topics



Leave a reply



Submit