是否可以将单级 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 个模型,User
和 Profile
。
然后我希望 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)
我有一个 JSON 响应,其中包含有关用户的信息。
{
"userId": "123456789",
"email": "\"some.email@some.domain.tld",
"firstName": "\"foo\"",
"lastName": "\"bar\"",
"name": "\"foo bar",
"bio": "\"boo baz\"",
"age": "42"
}
我想通过一个请求从同一个 JSON 创建 2 个模型,User
和 Profile
。
然后我希望 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)