Парсинг пользователя из json, внутри которого находится пользовательский объект (с Codable) - PullRequest
0 голосов
/ 23 мая 2019

Допустим, у меня есть следующий объект User:

struct User: Codable {
    let id: Int
}

И получение следующего json из API:

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

Очевидно, что кодируемый пользователь не будет анализировать.Есть ли способ сделать это, кроме создания объекта-обертки?Спасибо.

Редактировать: я получил несколько ответов с обертками - я знаю этот подход, но мне было любопытно альтернативный способ.Если это лучший способ сделать это или нет, не имеет значения.

Ответы [ 3 ]

2 голосов
/ 23 мая 2019

Вы можете использовать containers в Codable для получения nested data from JSON.

Контейнеры = Не требуется объект Wrapper

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, вы можете сохранить значение id, используя single object вместо создания wrapper object.

Примечание: В JSON предоставленном вами образцеid имеет тип String.Но в определении struct вы используете id типа Int.Код, который я дал, после преобразования String to Int.Если вы сделали опечатку, используйте значение string как есть.

Предложение - Используйте id как Int? вместо Int.Лучше не хранить никаких значений, чем мусорных (например, в данном случае 0)

2 голосов
/ 23 мая 2019

Две ошибки: корневой объект отсутствует, а тип id равен String (обратите внимание на двойные кавычки).

При Codable вы должны всегда анализировать JSON сверху

struct Root : Codable {
    let user : User
}

struct User : Codable {
    let id: String
}

Альтернативно декодировать в словарь, но это делает использование Codable бессмысленным.

0 голосов
/ 23 мая 2019

Самая простая модель для вашего JSON:

import Foundation

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

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