У меня есть одна простая структура:
struct Object: Codable {
let year: Int?
…
}
Это нормально, когда JSON декодируется как { "year": 10, … } или нет year в JSON.
Но не удастся декодировать, если ключ JSON имеет другой тип: { "year": "maybe string value" }
Как я мог не завершить процесс декодирования, если тип не соответствует необязательному свойству?
Спасибо.

Реализовать 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)
}
Пример:
{ "year": "10"}, object равно: Object(year: nil){ "year": 10}, object равно: Object(year: Optional(10))Да это оно. Лучше, чтобы вы предпочли изменить ответ API, чтобы вернуть согласованные типы для ключей.
Другого способа справиться с этим нет. Вы не можете настроить JSONDecoder для такой реализации.
Я использую Scripting Bridge для связи с другими приложениями Mac через Apple Event. Так что я не могу изменить ответ. В лицо должен сказать, что вся реакция с другой стороны через несколько раз изменится. Но небольшое изменение должно быть в порядке. Это пользователь ожидает.
Спасибо за ответ. Я надеюсь, что Apple улучшит декодер, чтобы сделать для нас больше пользовательских опций.
Могу ли я настроить JSONDecoder, чтобы это произошло, но не настроить структуру Codable? Больно реализовывать все подобные вещи.