Swift Academy · Урок

Работа с необязательными и вложенными типами

Безопасно декодируйте необязательные значения и вложенные структуры.

Урок 4 из 413 шагов

«Работа с необязательными и вложенными типами» — бесплатный урок Swift Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.

Опциональные свойства

Опциональное свойство автоматически поддерживает Codable, если его обёрнутый тип поддерживает этот протокол. Отсутствующий ключ JSON декодируется в nil, а присутствующий — обычным образом.

import Foundation

struct User: Codable {
    var name: String
    var nickname: String?
}

let json = "{\"name\":\"Ada\"}"
let u = try JSONDecoder().decode(User.self, from: json.data(using: .utf8)!)
print(u.name, u.nickname ?? "-")

Кодирование опциональных значений nil

По умолчанию опциональное значение nil полностью исключается из закодированного JSON, благодаря чему полезная нагрузка становится меньше.

import Foundation

struct User: Codable {
    var name: String
    var nickname: String?
}

let data = try JSONEncoder().encode(User(name: "Ada", nickname: nil))
print(String(data: data, encoding: .utf8)!)

Явный null декодируется в nil

Если JSON содержит явное значение null для опционального свойства, оно декодируется в nil, а не вызывает ошибку.

import Foundation

struct User: Codable {
    var name: String
    var age: Int?
}

let json = "{\"name\":\"Ada\",\"age\":null}"
let u = try JSONDecoder().decode(User.self, from: json.data(using: .utf8)!)
print(u.age == nil)

Вложенные структуры Codable

Создавайте модели, вкладывая типы Codable друг в друга. Внешний тип автоматически кодирует и декодирует внутренний.

import Foundation

struct Address: Codable { var city: String; var zip: String }
struct Person: Codable { var name: String; var address: Address }

let p = Person(name: "Lee", address: Address(city: "Rome", zip: "00100"))
let data = try JSONEncoder().encode(p)
print(String(data: data, encoding: .utf8)!)

Декодирование вложенных структур

Обратное преобразование тоже работает: вложенные объекты JSON декодируются во вложенные свойства структуры.

import Foundation

struct Address: Codable { var city: String }
struct Person: Codable { var name: String; var address: Address }

let json = "{\"name\":\"Lee\",\"address\":{\"city\":\"Rome\"}}"
let p = try JSONDecoder().decode(Person.self, from: json.data(using: .utf8)!)
print(p.address.city)

Опциональные вложенные типы

Вложенная структура сама может быть опциональной. Если ключ отсутствует, всё вложенное значение становится равным nil.

import Foundation

struct Address: Codable { var city: String }
struct Person: Codable { var name: String; var address: Address? }

let json = "{\"name\":\"Lee\"}"
let p = try JSONDecoder().decode(Person.self, from: json.data(using: .utf8)!)
print(p.address?.city ?? "no address")

Массивы элементов Codable

Массив элементов типа Codable сам является Codable. Он напрямую соответствует массиву объектов JSON.

import Foundation

struct Tag: Codable { var name: String }
struct Post: Codable { var title: String; var tags: [Tag] }

let p = Post(title: "Hi", tags: [Tag(name: "swift"), Tag(name: "json")])
let data = try JSONEncoder().encode(p)
print(String(data: data, encoding: .utf8)!)

Декодирование массивов структур

Декодирование массива объектов JSON даёт массив Swift с типизированными значениями, по которому можно выполнять итерацию.

import Foundation

struct Tag: Codable { var name: String }

let json = "[{\"name\":\"a\"},{\"name\":\"b\"}]"
let tags = try JSONDecoder().decode([Tag].self, from: json.data(using: .utf8)!)
for t in tags { print(t.name) }

Опциональные массивы

Опциональный массив различает состояния «ключ отсутствует» (nil) и «ключ присутствует, но массив пуст» ([]). Оба состояния допустимы и имеют смысл.

import Foundation

struct Box: Codable { var items: [String]? }

let a = try JSONDecoder().decode(Box.self, from: "{}".data(using: .utf8)!)
let b = try JSONDecoder().decode(Box.self, from: "{\"items\":[]}".data(using: .utf8)!)
print(a.items == nil, b.items == [])

Глубоко вложенные структуры

Вложенность может достигать нескольких уровней: структуры внутри массивов внутри структур. Codable рекурсивно обрабатывает каждый уровень.

import Foundation

struct Comment: Codable { var text: String }
struct Article: Codable { var title: String; var comments: [Comment] }
struct Feed: Codable { var articles: [Article] }

let feed = Feed(articles: [Article(title: "A", comments: [Comment(text: "hi")])])
let data = try JSONEncoder().encode(feed)
print(String(data: data, encoding: .utf8)!)

Полный цикл с опциональными и вложенными значениями

Если объединить всё изученное, опциональные поля, вложенные структуры и массивы сохраняются без изменений после полного цикла кодирования и декодирования.

import Foundation

struct Address: Codable { var city: String }
struct Person: Codable {
    var name: String
    var address: Address?
    var hobbies: [String]
}

let p = Person(name: "Mo", address: Address(city: "Cairo"), hobbies: ["chess"])
let data = try JSONEncoder().encode(p)
let back = try JSONDecoder().decode(Person.self, from: data)
print(back.address?.city ?? "-", back.hobbies.first ?? "-")

Быстрая проверка: опциональные и вложенные типы

Проверьте, насколько вы поняли работу с опциональными и вложенными типами Codable.

Повторение: опциональные и вложенные типы

Вы узнали, как Codable работает с более сложными структурами данных:

  • Опциональные свойства допускают отсутствующие ключи и явное значение null, декодируя их в nil.
  • По умолчанию опциональные значения nil исключаются при кодировании.
  • Вложенные структуры и массивы Codable кодируются и декодируются рекурсивно.
  • Опциональные массивы различают отсутствие значения (nil) и пустой массив ([]).
Можно начать бесплатно

Изучай Swift с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
122
Уроки
409

Часто задаваемые вопросы

Урок «Работа с необязательными и вложенными типами» бесплатный?

Да — полный текст урока «Работа с необязательными и вложенными типами» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.

Чему я научусь в уроке «Работа с необязательными и вложенными типами»?

Безопасно декодируйте необязательные значения и вложенные структуры. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Swift Academy?

Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Работа с необязательными и вложенными типами»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Swift Academy?

Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Соответствие Codable
  2. Кодирование с помощью JSONEncoder
  3. Декодирование с помощью JSONDecoder
  4. Работа с необязательными и вложенными типами
← Назад к Swift Academy