Swift Codable - 解码嵌套字典

Swift Codable - decode nested dictionary

假设我有这样的字典:

{"user_data":{"id":3,"name":"Damian D","email":"aaa@aaa.pl"},"status":true}

如何使用 Codable 协议将 user_data 解码为这样的 struct:

struct User: Codable {
    private enum CodingKeys: String, CodingKey {
        case id
        case username = "name"
        case email
    }

    let id:       Int
    let username: String
    let email:    String
}

我需要把这个子字典转换成数据,还是有更简单的方法?

创建一个具有 userData 类型 User 成员的新结构。

struct Response: Codable {
    private enum CodingKeys: String, CodingKey {
        case userData = "user_data"
        case status
    }

    let userData: User
    let status:   Bool
}

如果您创建嵌套的编码键,您将仅使用一个数据模型完成对响应的解码。

鉴于以下 JSON 响应:

let data = """
{
    "user_data": {
        "id":3,
        "name":"Damian D",
        "email":"aaa@aaa.pl"

    },
    "status":true
}
""".data(using: .utf8, allowLossyConversion: false)!

和以下数据模型:

public struct User: Decodable {

    var id: Int
    var name: String
    var email: String

    // MARK: - Codable
    private enum RootCodingKeys: String, CodingKey {

        case userData = "user_data"

        enum NestedCodingKeys: String, CodingKey {
            case id
            case name
            case email
        }
    }

    required public init(from decoder: Decoder) throws {

        let rootContainer = try decoder.container(keyedBy: RootCodingKeys.self)
        let userDataContainer = try rootContainer.nestedContainer(keyedBy: RootCodingKeys.NestedCodingKeys.self, forKey: .userData)

        self.id = try userDataContainer.decode(Int.self, forKey: .id)
        self.name = try userDataContainer.decode(String.self, forKey: .name)
        self.email = try userDataContainer.decode(String.self, forKey: .email)
    }
}

您可以将您的响应解码为单个对象:

let decoder = JSONDecoder()
let user = try? decoder.decode(User.self, from: data)