Может ли dataCompanies быть nil при декодировании JSON в Swift?
Что проверяют
Знаете ли вы, как синтезированный Decodable обращается с опциональными свойствами и в каких случаях декодер вернёт nil, а в каких бросит ошибку. Следом обычно спрашивают, что будет, если в массиве пришла одна битая компания.
Как отвечать
Всё зависит от объявления свойства. Для let dataCompanies: [Company]? компилятор генерирует decodeIfPresent, поэтому:
- ключа нет в JSON: будет nil, ошибки нет;
- значение
null: тоже nil; - пришёл не тот тип, например объект вместо массива: не nil, а
DecodingError.typeMismatch, и падает декодирование всего ответа; - битый элемент массива: у одной компании нет
idили он пришёл строкой. Ошибка элемента пробрасывается наверх, и весьResponseне декодируется.
Если свойство не опциональное, отсутствие ключа даёт DecodingError.keyNotFound, а null даёт valueNotFound.
Отдельно назовите самый частый источник «загадочного» nil: несовпадение имени. Сервер присылает data_companies, а в модели dataCompanies. Для опционального свойства это не ошибка, декодер честно не находит ключ и молча ставит nil. Лечится decoder.keyDecodingStrategy = .convertFromSnakeCase или явными CodingKeys.
Когда нужна терпимость к мусору, пишут свой init(from:): например, try? container.decode([Company].self, forKey: .dataCompanies), чтобы неверный тип осознанно превращался в nil, или декодируют элементы по одному и отбрасывают битые. Для отладки ловите DecodingError целиком и смотрите codingPath в контексте ошибки: он показывает точный путь до проблемного поля.
Где спотыкаются
Утверждают, что неверный тип даёт nil. Это не так, JSONDecoder бросает typeMismatch, и без do/catch вы теряете весь ответ.
Делают всё подряд опциональным «на всякий случай». Нарушения контракта с бэкендом перестают быть видны, и вместо понятной ошибки в логе пользователь получает пустой экран.
Объявляют let dataCompanies: [Company]? = [] с начальным значением. Синтезированный декодер такое свойство пропускает, компилятор предупреждает, и значение из JSON в модель не попадёт никогда.