> Может ли dataCompanies быть nil при декодировании JSON в Swift? (iOS, Swift)
Уровень: senior · Роль: mobile · Категория: Технические вопросы
Компании: Ozon
Стек: iOS, Swift
> Пример ответа
Короткий ответ
Да, может, но не из-за самого JSON. если dataCompanies объявлен как non-optional свойство, то JSONDecoder не присвоит ему nil напрямую: при отсутствии ключа или null декодирование упадёт с ошибкой keyNotFound или valueNotFound. nil в рантайме возможен только если свойство optional, инициализировано вручную или используется кастомный init(from:), который явно выставляет nil.
Подробное объяснение
В Swift JSONDecoder работает через Decodable и init(from:). Для non-optional свойства типа [Company] декодер ожидает, что ключ есть и значение не null. Иначе выбрасывается DecodingError:
-
keyNotFound, если ключа нет; -
valueNotFound, если значениеnull; -
typeMismatch, если тип не совпадает.
Если свойство объявлено как [Company]?, то null или отсутствие ключа дадут nil без ошибки. Но это уже свойство модели, а не поведение JSON. Также nil может появиться, если модель создаётся не через декодер, а вручную, или если кастомный init(from:) присваивает nil при определённых условиях.
Важный нюанс: decodeIfPresent не делает non-optional свойство optional. Он возвращает optional, и дальше нужно решить, что делать: присвоить значение по умолчанию, выбросить ошибку или оставить nil в optional свойстве.
На практике
На senior-уровне важно разделять три вещи:
-
контракт API: ключ обязателен или опционален;
-
модель: свойство optional или нет;
-
стратегия декодирования: строгая или мягкая.
Если API может не вернуть dataCompanies, а бизнес-логика это допускает, свойство делают optional или задают default []. Если поле обязательное, лучше оставить non-optional и дать декодированию упасть, чтобы ошибка была явной. смешивать эти подходы без причины - источник багов.
Пример кода
SWIFTstruct Response: Decodable {let dataCompanies: [Company] // non-optional}// JSON без ключа -> keyNotFound// JSON с null -> valueNotFoundstruct ResponseOptional: Decodable {let dataCompanies: [Company]? // null или отсутствие ключа -> nil}struct ResponseDefault: Decodable {let dataCompanies: [Company]init(from decoder: Decoder) throws {let container = try decoder.container(keyedBy: CodingKeys.self)dataCompanies = try container.decodeIfPresent([Company].self, forKey: .dataCompanies) ?? []}}
Как отвечать на собеседовании
Сначала уточните, что значит "может ли быть nil": в JSON, в модели или в рантайме. Затем объясните поведение JSONDecoder для non-optional и optional свойств, упомяните DecodingError и decodeIfPresent. В конце добавьте, что решение зависит от контракта API и бизнес-требований, а не только от синтаксиса Swift.
Что проверяет интервьюер
Понимание difference между optional в модели и null в JSON, знание DecodingError, умение выбирать между строгим и мягким декодированием, а также способность отделять контракт API от реализации модели.
Типичные ошибки
-
считать, что non-optional свойство может стать
nilпри декодировании; -
путать
decodeиdecodeIfPresent; -
делать все поля optional "на всякий случай", теряя явность контракта;
-
игнорировать
keyNotFoundиvalueNotFoundкак разные сценарии; -
использовать
try?вокруг всего декодирования и терять причину ошибки.
> Похожие задачи по mobile
Какой опыт с Objective-C
Как реализовать поддержку кодирования и декодирования JSON без классов в Swift
Как посчитать количество уникальных значений в колонке DataFrame?
Что такое дефолтный поток в Kotlin Coroutines?
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью