Сделать так, чтобы Swift JSONDecoder не терпел неудачу, если тип ключа не совпадает

У меня есть одна простая структура:

struct Object: Codable {
    let year: Int?
    …
}

Это нормально, когда JSON декодируется как { "year": 10, … } или нет year в JSON.
Но не удастся декодировать, если ключ JSON имеет другой тип: { "year": "maybe string value" }

Как я мог не завершить процесс декодирования, если тип не соответствует необязательному свойству?

Спасибо.

Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
1
0
838
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Реализовать init(from:) в struct Object. Создайте enum CodingKeys и добавьте cases для всех properties, которые вы хотите проанализировать.

В init(from:) проанализируйте keys вручную и проверьте, можно ли year из JSON декодировать как Int. Если да, назначьте его свойству Object'syear, иначе не делайте этого.

struct Object: Codable {
    var year: Int?

    enum CodingKeys: String,CodingKey {
        case year
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        if let yr = try? values.decodeIfPresent(Int.self, forKey: .year) {
            year = yr
        }
    }
}

Разберите ответ JSON, например,

do {
    let object = try JSONDecoder().decode(Object.self, from: data)
    print(object)
} catch {
    print(error)
}

Пример:

  1. Если JSON равно { "year": "10"}, object равно: Object(year: nil)
  2. Если JSON равно { "year": 10}, object равно: Object(year: Optional(10))

Могу ли я настроить JSONDecoder, чтобы это произошло, но не настроить структуру Codable? Больно реализовывать все подобные вещи.

user25917 28.06.2019 20:30

Да это оно. Лучше, чтобы вы предпочли изменить ответ API, чтобы вернуть согласованные типы для ключей.

PGDev 28.06.2019 20:31

Другого способа справиться с этим нет. Вы не можете настроить JSONDecoder для такой реализации.

PGDev 28.06.2019 20:33

Я использую Scripting Bridge для связи с другими приложениями Mac через Apple Event. Так что я не могу изменить ответ. В лицо должен сказать, что вся реакция с другой стороны через несколько раз изменится. Но небольшое изменение должно быть в порядке. Это пользователь ожидает.

user25917 28.06.2019 20:35

Спасибо за ответ. Я надеюсь, что Apple улучшит декодер, чтобы сделать для нас больше пользовательских опций.

user25917 28.06.2019 20:36

Другие вопросы по теме