如果密钥不存在,解码失败

Decoding fails if keys not present

如果密钥不存在,解码将失败。如果还缺少密钥,如何安全解码。

我已经使用了 OptionalNil 值,但仍然无法解码对象。

下面我的Json

{
   "mandatory":true,
   "dynamic_obj":[
      {
         "dt":"2021-09-22 01:29:52",
         "url":"https://res._22_01_29.pdf",
         "desc":"PAN CARD",
         "flag":1,
         "count":"2",
         "field":"pan_card",
         "address":"300-435, Nattu Muthu St, Sheethammal Colony, Venus Colony, Chennai, Tamil Nadu 600018, India",
         "visible":true,
         "latitude":13.0389309,
         "longitude":80.2473746
      },
      {
         "url":"https://res.cloudin/no-image.jpg",
         "desc":"driving License",
         "count":"2",
         "field":"driving_license",
         "visible":true
      }
   ]
}

型号class以下

struct Dynamic_obj : Codable {
    var dt : String?
    var url : String?
    let desc : String?
    var flag : Int?
    let count : String?
    let field : String?
    let visible : Bool?
    
    var bankname : String = "NA"
    var pdfPassword : String = "NA"
    var latitude : String = "NA"
    var longitude : String = "NA"
    var address : String = "NA"

    enum CodingKeys: String, CodingKey {

        case dt = "dt"
        case url = "url"
        case desc = "desc"
        case flag = "flag"
        case count = "count"
        case field = "field"
        case visible = "visible"
        
        case bankname = "bankname"
        case pdfPassword = "pdfPassword"
        case latitude = "latitude"
        case longitude = "longitude"
        case address = "address"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        dt = try values.decodeIfPresent(String.self, forKey: .dt)
        url = try values.decodeIfPresent(String.self, forKey: .url)
        desc = try values.decodeIfPresent(String.self, forKey: .desc)
        flag = try values.decodeIfPresent(Int.self, forKey: .flag)
        count = try values.decodeIfPresent(String.self, forKey: .count)
        field = try values.decodeIfPresent(String.self, forKey: .field)
        visible = try values.decodeIfPresent(Bool.self, forKey: .visible)
        
        bankname = try values.decodeIfPresent(String.self, forKey: .bankname) ?? "NA"
        pdfPassword = try values.decodeIfPresent(String.self, forKey: .pdfPassword) ?? "NA"
        latitude = try values.decodeIfPresent(String.self, forKey: .latitude) ?? "NA"
        longitude = try values.decodeIfPresent(String.self, forKey: .longitude) ?? "NA"
        address = try values.decodeIfPresent(String.self, forKey: .address) ?? "NA"
    }

}


                            let decoder = JSONDecoder()
                            do {
                                let responseModel = try decoder.decode(LoanDocxPending.self, from: data)
                                if let mandotory = responseModel.mandatory{
                                    self.visibleDocuments["Identity Proof-~id_proof"] = idProof
                                    self.visibleTitle.append("Identity Proof")
                                }
                            } catch {
                                print("error")
                                
                            }

struct LoanDocxPending :Codable {
    let mandatory : Bool?
    var dynamic_obj : [Dynamic_obj]?

    enum CodingKeys: String, CodingKey {

        case mandatory = "mandatory"
        case dynamic_obj = "dynamic_obj"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        mandatory = try values.decodeIfPresent(Bool.self, forKey: .mandatory)
        dynamic_obj = try values.decodeIfPresent([Dynamic_obj].self, forKey: .dynamic_obj)
    }

}

首先,您的大部分代码都不需要,例如 init 方法和几乎所有的 CodingKeys。

其次,如评论中所述,而不是打印无意义的文字“错误”打印 error 实例。它会告诉你 latitudelongitudeDouble,而不是 String

此模型与问题中的 JSON 匹配

struct DynamicObj : Codable {
    let dt : String?
    let url, desc : String
    let flag : Int?
    let count, field : String
    let visible : Bool
    
    var bankname, pdfPassword, address : String?
    var latitude, longitude : Double?
}

struct LoanDocxPending :Codable {
    let mandatory : Bool
    var dynamicObj : [DynamicObj]

    enum CodingKeys: String, CodingKey {
        case mandatory,dynamicObj = "dynamic_obj"
    }
}

let decoder = JSONDecoder()
do {
    let responseModel = try decoder.decode(LoanDocxPending.self, from: data)
    print(responseModel.mandatory)
} catch {
    print("error", error)
    
}