swift 如果键具有String格式值类型字典,如何创建模型来解码API响应

yxyvkwin  于 2023-04-28  发布在  Swift
关注(0)|答案(1)|浏览(116)

这是我从 Postman 那里得到的Post API响应,检查表完成有两个关键“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
        }
    }

我已经创建了如下模型,但JsonDecoder无法将响应Map到我创建的模型,我将“checklistDone”和workWithPrice标记为Stein?

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"
    }
}

请指导我的模型,我已经创建是错误的或其他任何东西

csbfibhn

csbfibhn1#

我已经使用了下面的模型,我能够解码模型。

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)
    }

}

你解码的时候根对象应该是APIData,因为你上面AdditionalData的响应里面有一个根对象,见下面代码。

let jsonDecoder = JSONDecoder()
        do{
            let response = try jsonDecoder.decode(APIData.self, from: data)
            completion(response, nil)
        }catch(let error){
            completion(nil,error)
        }

相关问题