swift 中标准嵌套 JSON 的可解码包装器

Decodable wrapper for standard nested JSON in swift

我正在使用遵循非常相似的响应结构的 api:

{
    "error": "string item",
    "success": true,
    "result": {
        "users" : [
              {
                "id": "20001",
                "firstname": "John",
                "lastname" : "Smith",
                "address": "123 king street",
                "email": "john.smith@gmail.com",
                "mobile": "0412345678"
              },
              {
                "id": "20002",
                "firstname": "Jack",
                "lastname": "Master",
                "address": "123 rainbow road",
                "email": "jack.master@gmail.com",
                "mobile": "0412345678"
              }
        ]
    }
}

api returns 基于端点的不同结果。我想创建一个标准的可解码 json 响应结构。然后我为每个不同的结果类型创建一个新的可解码结构。

像这样的东西是理想的:

struct JSONResponse<T: Decodable>: Decodable {
    var error: String
    var success: Bool
    var result: T
}

这是我正在尝试做的事情

struct User: Decodable {
    var id: String
    var firstName: String
    var lastName: String
    var email: String
    
    enum CodingKeys: String, CodingKey {
        case users
    }
    
    enum UserKeys: String, CodingKey {
        case id, firstName = "firstname", lastName = "lastname", email, mobile
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let nestedContainer = try container.nestedContainer(keyedBy: UserKeys.self, forKey: .users)

        id = try nestedContainer.decode(String.self, forKey: .id)
        firstName = try nestedContainer.decode(String.self, forKey: .firstName)
        lastName = try nestedContainer.decode(String.self, forKey: .lastName)
        email = try nestedContainer.decode(String.self, forKey: .email)
    }
    
}

然后像这样解码一些不同的响应

let res = try! JSONDecoder().decode(JSONResponse<User>.self, from: responseData!)
    

在这种特定情况下,您有多个 User 对象,因此您需要某种容器:

struct Users: Decodable {
   var users: [User]
}

User也不用这么复杂:

struct User: Decodable {
   var id: String
   var firstName: String
   var lastName: String
   var email: String
}

然后解码为:

let users = JSONDecoder().decode(JSONResponse<Users>.self, from: responseData)