This is Post API response which I am getting from postman here checklist done have two keys "checklist_done", "work_with_price":
{
"additional_data": {
"id": 215,
"booking_id": 221,
"checklist_done": "{\"4\":\"Gear Oil\",\"2\":\"Engine Oil Change\",\"3\":\"Air and Oil Filter\"}",
"work_with_price": "{\"chain\":\"145\",\"Battery\":\"58\"}",
"work_price": "203",
"estimated_price": 149,
"discount_code": "admin",
"mechanic_profit": "200",
"discount": 0,
"ccavenue_charge": 0,
"ccavenue_gst": 0,
"total_price": "352",
"payment_method": null,
"gateway": null,
"payment_response": null,
"status": "pending",
"paymentmode": null,
"bankname": null,
"txnid": null,
"banktxnid": null,
"txndate": null,
"created_at": "2023-04-27T18:20:07.000000Z",
"updated_at": "2023-04-27T18:27:19.000000Z",
"admin_discount": 0
}
}
I have created model like below but JsonDecoder
is unable to map response to my created model.
I marked checklistDone
and workWithPrice
as String?
.
struct AdditionalData: Codable {
var id, bookingID: Int?
var checklistDone: String?
var workWithPrice: String?
var workPrice: String?
var estimatedPrice: Int?
var discountCode, mechanicProfit: String?
var discount, ccavenueCharge, ccavenueGst: Int?
var totalPrice: String?
var paymentMethod, gateway, paymentResponse: String?
var status: String?
var paymentmode, bankname: String?
var txnid, banktxnid: String?
var txndate: String?
var createdAt, updatedAt: String?
var adminDiscount: Int?
enum CodingKeys: String, CodingKey {
case id
case bookingID = "booking_id"
case checklistDone = "checklist_done"
case workWithPrice = "work_with_price"
case workPrice = "work_price"
case estimatedPrice = "estimated_price"
case discountCode = "discount_code"
case mechanicProfit = "mechanic_profit"
case discount
case ccavenueCharge = "ccavenue_charge"
case ccavenueGst = "ccavenue_gst"
case totalPrice = "total_price"
case paymentMethod = "payment_method"
case gateway
case paymentResponse = "payment_response"
case status
case paymentmode, bankname, txnid, banktxnid, txndate
case createdAt = "created_at"
case updatedAt = "updated_at"
case adminDiscount = "admin_discount"
}
}
Please guide me the model I have created is wrong or anything else.
I have used below model and I am able to decode the model.
struct APIData: Codable {
let additionalData: AdditionalData?
enum CodingKeys: String, CodingKey {
case additionalData = "additional_data"
}
}
struct AdditionalData : Codable {
let adminDiscount : Int?
let bankname : String?
let banktxnid : String?
let bookingId : Int?
let ccavenueCharge : Int?
let ccavenueGst : Int?
let checklistDone : String?
let createdAt : String?
let discount : Int?
let discountCode : String?
let estimatedPrice : Int?
let gateway : String?
let id : Int?
let mechanicProfit : String?
let paymentMethod : String?
let paymentResponse : String?
let paymentmode : String?
let status : String?
let totalPrice : String?
let txndate : String?
let txnid : String?
let updatedAt : String?
let workPrice : String?
let workWithPrice : String?
enum CodingKeys: String, CodingKey {
case adminDiscount = "admin_discount"
case bankname = "bankname"
case banktxnid = "banktxnid"
case bookingId = "booking_id"
case ccavenueCharge = "ccavenue_charge"
case ccavenueGst = "ccavenue_gst"
case checklistDone = "checklist_done"
case createdAt = "created_at"
case discount = "discount"
case discountCode = "discount_code"
case estimatedPrice = "estimated_price"
case gateway = "gateway"
case id = "id"
case mechanicProfit = "mechanic_profit"
case paymentMethod = "payment_method"
case paymentResponse = "payment_response"
case paymentmode = "paymentmode"
case status = "status"
case totalPrice = "total_price"
case txndate = "txndate"
case txnid = "txnid"
case updatedAt = "updated_at"
case workPrice = "work_price"
case workWithPrice = "work_with_price"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
adminDiscount = try values.decodeIfPresent(Int.self, forKey: .adminDiscount)
bankname = try values.decodeIfPresent(String.self, forKey: .bankname)
banktxnid = try values.decodeIfPresent(String.self, forKey: .banktxnid)
bookingId = try values.decodeIfPresent(Int.self, forKey: .bookingId)
ccavenueCharge = try values.decodeIfPresent(Int.self, forKey: .ccavenueCharge)
ccavenueGst = try values.decodeIfPresent(Int.self, forKey: .ccavenueGst)
checklistDone = try values.decodeIfPresent(String.self, forKey: .checklistDone)
createdAt = try values.decodeIfPresent(String.self, forKey: .createdAt)
discount = try values.decodeIfPresent(Int.self, forKey: .discount)
discountCode = try values.decodeIfPresent(String.self, forKey: .discountCode)
estimatedPrice = try values.decodeIfPresent(Int.self, forKey: .estimatedPrice)
gateway = try values.decodeIfPresent(String.self, forKey: .gateway)
id = try values.decodeIfPresent(Int.self, forKey: .id)
mechanicProfit = try values.decodeIfPresent(String.self, forKey: .mechanicProfit)
paymentMethod = try values.decodeIfPresent(String.self, forKey: .paymentMethod)
paymentResponse = try values.decodeIfPresent(String.self, forKey: .paymentResponse)
paymentmode = try values.decodeIfPresent(String.self, forKey: .paymentmode)
status = try values.decodeIfPresent(String.self, forKey: .status)
totalPrice = try values.decodeIfPresent(String.self, forKey: .totalPrice)
txndate = try values.decodeIfPresent(String.self, forKey: .txndate)
txnid = try values.decodeIfPresent(String.self, forKey: .txnid)
updatedAt = try values.decodeIfPresent(String.self, forKey: .updatedAt)
workPrice = try values.decodeIfPresent(String.self, forKey: .workPrice)
workWithPrice = try values.decodeIfPresent(String.self, forKey: .workWithPrice)
}
}
Your root object should be APIData while you are decoding because you have an root object in your response above AdditionalData, see below code.
let jsonDecoder = JSONDecoder()
do{
let response = try jsonDecoder.decode(APIData.self, from: data)
completion(response, nil)
}catch(let error){
completion(nil,error)
}