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
Make Property of Type and Also Conform to Protocol in Swift
Swift - Avaudioplayer, Sound Doesn't Play Correctly
What Does "Get" Mean in a Protocol's Property Declaration
Change Uibarbuttonitem from Uisearchbar
Custom Swift Encoder/Decoder for the Strings Resource Format
How to Completely Remove Realm Database from iOS
What's the Equivalent to String.Localizedstringwithformat(_:_:) for Swiftui's Localizedstringkey
Unsaferawpointer Assumingmemorybound VS. Bindmemory
How to Disable Vertical Scroll in Tabview with Swiftui
How to Find Actual Swiftui API Documentation (And Not Just the Developer Documentation)
Extending Collection with a Recursive Property/Method That Depends on the Element Type
Parameters After Opening Bracket
Get an Array of Dates of the Current Week Starting on Monday
Select Multiple Rows in Tableview and Tick the Selected Ones