是否可以将单级 JSON 解码为 2 个独立的模型?

Is it possible to decode single level JSON into 2 separate models?

我有一个 JSON 响应,其中包含有关用户的信息。

{
  "userId": "123456789",
  "email": "\"some.email@some.domain.tld",
  "firstName": "\"foo\"",
  "lastName": "\"bar\"",
  "name": "\"foo bar",
  "bio": "\"boo baz\"",
  "age": "42"
}

我想通过一个请求从同一个 JSON 创建 2 个模型,UserProfile

然后我希望 Profile 成为 User 结构上的 属性。

目前,我的标准结构如下所示 -

struct User: Codable, Equatable {
    var userId: String
    var email: String
    var firstName: String
    var lastName: String
    var name: String?
    var bio: String?
    var age: Int?
}

不过我更愿意做这样的事情 -

struct User: Codable, Equatable {
    var userId: String
    var email: String
    var profile: UserProfile // I'd like to wrap the profile info up in this field
}

struct UserProfile: Codable, Equatable {
    var firstName: String
    var lastName: String
    var name: String?
    var bio: String?
    var age: Int?
}

由于响应中不存在 profile,我不明白如何将响应的其余部分解码到其中。

首先,您应该考虑在模型上制作所有字段 immutable

最好不要更改您的数据,而是创建一个更新的副本。

但是,这应该有效 -

let json = Data("""
 {
   "userId": "123456789",
   "email": "some.email@some.domain.tld",
   "firstName": "foo",
   "lastName": "bar",
   "name": "foo bar",
   "bio": "boo baz",
   "age": 42
 }
""".utf8)

struct User: Codable, Equatable {
    let userId: String
    let email: String
    let profile: UserProfile

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        userId = try values.decode(String.self, forKey: .userId)
        email = try values.decode(String.self, forKey: .email)
        profile = try UserProfile(from: decoder)
    }

}

struct UserProfile: Codable, Equatable {
        let firstName: String
        let lastName: String
        let name: String?
        let bio: String?
        let age: Int?
}

var result = try! JSONDecoder().decode(User.self, from: json)
print(result.profile)