У меня есть ответ в формате JSON, содержащий информацию о пользователе.

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

Я хочу создать 2 модели, User и Profile из одного JSON, с помощью одного запроса.

Затем я хотел бы, чтобы 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 не существует в ответе, я не понимаю, как я могу декодировать в него остальную часть ответа.

3
Tim J 23 Ноя 2019 в 10:51

1 ответ

Лучший ответ

Во-первых, вам следует подумать о том, чтобы сделать все поля в вашей модели неизменяемыми.

Рекомендуется не изменять данные, а создавать обновленную копию.

Однако это должно сработать -

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)
4
nodediggity 23 Ноя 2019 в 08:13