从 json 中解析用户,其中包含用户对象(使用 Codable)

Parsing User from json that has user object inside (with Codable)

假设我有以下用户对象:

struct User: Codable {
    let id: Int
}

并通过 API 关注 json:

{
    "user": {
        "id": "22"
    }
}

显然,codable 用户不会解析。除了创建包装器对象之外,还有什么办法可以做到吗?谢谢。

编辑:我得到了一些关于包装器的答案——我知道这种方法,但我对另一种方法很好奇。是不是更好的方法是无关紧要的。

两个错误:缺少根对象并且id的类型是String(注意双引号)。

对于 Codable,您必须始终从顶部

解析 JSON
struct Root : Codable {
    let user : User
}

struct User : Codable {
    let id: String
}

或者解码为字典,但这使得 Codable 的使用毫无意义。

你可以在Codable中使用containers得到nested data from JSON.

容器 = 不需要包装器对象

struct User: Decodable {
    var id: Int

    enum CodingKeys: String, CodingKey {
        case user, id
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        let user = try values.nestedContainer(keyedBy: CodingKeys.self, forKey: .user)
        let idStr = try user.decode(String.self, forKey: .id)
         id = Int(idStr) ?? 0
    }
}

使用 containers,您可以使用 single object 存储 id 的值,而不是创建任何 wrapper object.

注意:JSON 中,您提供的示例 id 的类型为 String。但是在 struct 定义中,您使用的是 Int 类型的 id。我给出的代码是在转换 String to Int 之后。如果您打错了字,请按原样使用 string 值。

建议 - 使用 id 作为 Int? 而不是 Int。最好不要存储任何值而不是存储垃圾值(例如:在这种情况下为 0)

最简单的模型 JSON:

import Foundation

// MARK: - UserModel
struct UserModel: Codable {
let user: User
}

// MARK: - User
struct User: Codable {
let id: String
}