As the title says, Alamofire 5 is telling me that the data is missing, yet it is not.
This is the data I have in my console along with the error
dic=== {"lat": "26.9342246", "message": "Test", "lng": "-80.0942087", "receiver_id": "269", "messageType": "text", "chatType": "fix", "product_variant_id": "", "receiverType": "customer", "customer_id": "213", "itemType": "sell", "product_id": "25", "service_id": "", "fileName": ""}
Result: failure(Alamofire.AFError.responseSerializationFailed(reason: Alamofire.AFError.ResponseSerializationFailureReason.decodingFailed(error: Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "message", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"message\", intValue: nil) (\"message\").", underlyingError: nil)))))
Upload Failed: Response could not be decoded because of error:
The data couldn’t be read because it is missing.
These are my Decodable's
struct MessageModel : Decodable {
let data : [MessageModelData]?
let message : String
enum CodingKeys: String, CodingKey {
case message, data
}
}
struct MessageModelData : Decodable {
let fileType : String
let groupID, id : Int
let intetestCustomerID, itemType, message, messageType : String
let productID, productOwnerID, profileImg, profileName :String
let receiveID, receiverType, sendAt : String
enum CodingKeys: String, CodingKey {
case groupID = "groupId"
case intetestCustomerID = "intetest_customer_id"
case productID = "product_id"
case productOwnerID = "product_owner_id"
case receiveID = "receiveId"
case fileType, id, itemType, message, messageType, profileImg, profileName, receiverType, sendAt
}
}
Am I missing something? I changed message
to an optional and then it said unexpectedly found nil, I'm very confused as clearly the message variable is in the response.
Here's where it errors
func sendChatProductImage(header: String, parameter: String, coverdata: UIImage, mimetype : String ,vc: UIViewController, showHud: Bool,completion : @escaping(_ success : Bool, _ message : String, _ response : NSDictionary) -> Void) {
webService_obj.chatProductImageSend(header: header, withParameter: parameter, coverdata: coverdata, mimetypeExtention: mimetype, inVC: vc, showHud: showHud) { (response, success) in
if success{
let message = response["message"]
completion(success, message as! String, response )
}
}
}
EDIT:
I figured out why, but I don't know how to resolve it.
I have my upload here with Alamofire 5, and I have the decodable, but it is not properly decoding it to the right data, or I'm using the response wrong
AF.upload(
multipartFormData: { multipartFormData in
var dic = parameter.replacingOccurrences(of: "[", with: "{")
dic = dic.replacingOccurrences(of: "]", with: "}")
print("dic===",dic)
multipartFormData.append("\(dic)".data(using: String.Encoding.utf8)!, withName: "data")
if coverimageData != nil {
multipartFormData.append(coverimageData!, withName: "file", fileName: "chatImage.jpg", mimeType: "*/*")
}else{
multipartFormData.append("".data(using: String.Encoding.utf8)!, withName: "file")
}
},
with: uploadUrl).responseDecodable(of: MessageModel.self) { response in
print("Result: \(response)")
if hud {
Loader.init().hide(delegate: vc)
}
switch response.result {
case .success(let result):
let dataResponse = response.value(forKey: "data" as? NSDictionary)
completion(dataResponse, true)
case .failure(let error):
let err = error.localizedDescription
print("Upload Failed: \(err)")
completion([:], false)
self.presentAlertWithTitle(title: kAPPName, message: err, vc: vc)
break
}
}
As you can see your MessageModel
struct does not match the
json data you get from the server in response to yourupload
.
In particular there is no response
property. Similarly for MessageDataType
.
Try the following models, to decode the response you get from the server after you have sent your data to it:
struct PostResponse: Codable {
let response: MessageDataType <-- here
}
struct MessageDataType: Codable {
let status_code: Int
let message, data: String
}
and decode the response like this:
//...
with: uploadUrl).responseDecodable(of: PostResponse.self) { <-- here
//....
You will have to read the server docs to determine which of the properties
should be optional, in that case add ?
to it.
EDIT-1
To decode the response you are now showing, instead of the one you showed us before,
Optional("{\"response\":{\"status_code\":200,\"message\":\"Message sent successfully.\",\"data\":\"154\"}}")
use the following models:
struct PostResponse: Codable {
let response: StatusResponse
}
struct StatusResponse: Codable {
let status_code: Int
let message: String
let data: DataClass
}
struct DataClass: Codable {
let chatId, senderId, receiveId, senderType: String
let message, lat, lng, file: String
let fileName, fileType, messageType: String
}