如何使用 JSONDecoder 和 Swift 4 Decodabale class 解码

How to decode this using JSONDecoder and Swift 4 Decodabale class

我已经使用 JSONSerialization 对此进行了解码。但是为了我自己的知识和代码的维护。我想知道如何解码这个。

这是我目前拥有的:

let urlString = "site deleted" + "/DataSource/Mobile/?Action=MyProfile&uid=" + uid + "&uuid=" + uuid
    guard let url = URL(string: urlString) else {return}
    URLSession.shared.dataTask(with: url) { (data, _, error) in
        if let err = error {
            print("Handle MyProfileJSON error: ", err)
        }
        guard let data = data else {return}
        do {
            // swift 4.2 but we cant use it right now
            let profile = try JSONDecoder().decode(RequestResult.self, from: data)
        print(profile)
        completion(profile)
    } catch let err {
        print("Handle Decoder Error: ", err)
    }

}.resume()

我不太担心这些情况,但这就是我目前所遇到的情况。我知道我使用的大小写不是惯例,这就是为什么我用 JSONSerialization 这样做的原因,所以我可以使用 camelCase。如果你能帮我把它也转换成驼峰式,那就太棒了,但我的重点是使用 Decodable class 解码它。非常感谢,伙计们。

这是我的结构:

struct RequestResult: Decodable {
    var Action: String?
    var Params: [String: String]?
    var DATA: [String: String]?
}

struct Params: Decodable {
    var Action_get: String?
    var uid_get: String?
}

struct DATA: Decodable {
    var Id: String?
    var UserCode: String?
    var HomePhone: String?
    var Mobile: String?
    var WorkPhone: String?
    var Email: String?
    var AltEmail: String?
    var UnitNo: String?
    var StreetNo: String?
    var StreetName: String?
    var City: String?
    var StateProvince: String?
    var Country: String?
    var ZipPostalCode: String?
}

JSON的结构很清晰

  • 根对象RequestResult包含一个字符串和两个字典。
  • 字典被结构取代。
  • CodingKeys 可用于将键重命名为更有意义且符合命名约定的名称。枚举大小写的左侧是结构成员名称,右侧是原始 JSON 键。
  • 结构成员名称必须与字典键(或映射的 CodingKey)相匹配。
  • 结构名称是任意的。
  • 如果 JSON 始终包含键,则所有结构成员都可以声明为常量 (let) 和非可选成员。

    struct RequestResult: Decodable {
    
        private enum CodingKeys : String, CodingKey {
            case action = "Action", params = "Params", data = "DATA"
        }
    
        let action: String
        let params: Parameter
        let data: UserData
    }
    
  • 关键字 Params 的字典将重命名为 ParameterDATA 将重命名为 UserData

    struct Parameter: Decodable {
        private enum CodingKeys : String, CodingKey {
            case action = "Action_get", uid = "uid_get"
        }
    
        let action: String
        let get: String
    }
    
    struct UserData: Decodable {
    
        private enum CodingKeys : String, CodingKey {
            case id = "Id", userCode = "UserCode", homePhone = "HomePhone"
            case mobile = "Mobile", workPhone = "WorkPhone", email = "Email"
            case altEmail = "AltEmail", unitNo = "UnitNo", streetNo = "StreetNo"
            case streetName = "StreetName", city = "City", stateProvince = "StateProvince"
            case country = "Country", zipPostalCode = "ZipPostalCode"
        }
    
        let id: String, userCode, homePhone, mobile: String
        let workPhone, email, altEmail, unitNo: String
        let streetNo, streetName, city, stateProvince: String
        let country, zipPostalCode: String
    }