Reputation: 232
I am trying to upload (post) a JSON string using Alamofire and I'm getting an error that leads me to believe there is some issue in the dictionary encoding.
The array I am encoding is an array of objects, all of type String. It looks like this:
class SavedDeliveries: Codable { //not sure if this is the issue (I use this to store default values locally)
var fullName = ""
var address = ""
var city = ""
var zip = ""
var phone = ""
var orders = ""
var ordersListed = ""
var pickup = ""
}
The code including the Alamofire call looks like this:
func postData() {
let headers: HTTPHeaders = [
"Content-Type": "application/json",
"X-Master-Key": "xxx", //API Key
"X-Bin-Name": "deliverydata"]
let jsonEncoder = JSONEncoder()
let jsonData = try! jsonEncoder.encode(deliveryList)
let json = String(data: jsonData, encoding: String.Encoding.utf8)
print(json!) // printing the JSON and it is correct when validated.
AF.request("https://api.jsonbin.io/v3/b", method: .post, parameters: json, encoding: JSONEncoding.default, headers: headers).responseString { (response) in
switch response.result {
case .success:
print("was successful")
case let .failure(error):
print(error)
}
}
}
I expect it to upload the JSON file but I'm getting an error message that says this:
Cannot convert value of type 'String?' to expected argument type 'Parameters?' (aka 'Optional<Dictionary<String, Any>>')
Not sure if the AF call parameter is expecting a certain kind of dictionary key:value format. If this is not the right call format for uploading JSON, what do I need to change?
Thanks for any help. I'm not a full-time Swift developer but manage an app that is usually within my capabilities. This one has me stumped.
Upvotes: 0
Views: 512
Reputation: 12770
To make such a request using Alamofire, I'd recommend:
let headers: HTTPHeaders = [
"Content-Type": "application/json",
"X-Master-Key": "xxx", //API Key
"X-Bin-Name": "deliverydata"]
AF.request("https://api.jsonbin.io/v3/b",
method: .post,
parameters: deliveryList,
headers: headers).responseString { response in
switch response.result {
case .success:
print("was successful")
case let .failure(error):
print(error)
}
}
Even better, create a Decodable
response type and use responseDecodable
to parse it.
I would also suggest not using empty strings as your default values, that can easily lead to sending bad or invalid data to the backend.
Upvotes: 0
Reputation: 232
I guess I don't understand much about HTTP requests or Alamofire, but I was able to solve this issue with the following mods to my code (without Alamofire, which seems like overkill in this case).
func postData() {
// Prepare URL
let url = URL(string: "https://api.jsonbin.io/v3/b")
guard let requestUrl = url else { fatalError() }
// Prepare URL Request Object
var request = URLRequest(url: requestUrl)
request.httpMethod = "POST"
// Set HTTP Request Body
let header: HTTPHeaders = [
"Content-Type": "application/json",
"X-Master-Key": "xxx",
"X-Bin-Name": "deliverydata"
]
request.headers = header
let jsonEncoder = JSONEncoder()
let jsonData = try! jsonEncoder.encode(deliveryList)
let json = String(data: jsonData, encoding: String.Encoding.utf8)
request.httpBody = json!.data(using: String.Encoding.utf8)
// Perform HTTP Request
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
// Check for Error
if let error = error {
print("Error took place \(error)")
return
}
// Convert HTTP Response Data to a String
if let data = data, let dataString = String(data: data, encoding: .utf8) {
print("Response data string:\n \(dataString)")
}
}
task.resume()
}
Upvotes: 0