Добавить объявление

Работа с JSON в Swift: Codable, Encodable и Decodable

Swift предлагает удобные протоколы для преобразования объектов в JSON и обратно. Разберем, как это работает.

Основные протоколы:


  • Decodable: только декодирование (JSON → объект).

  • Encodable: только кодирование (объект → JSON).

  • Codable: и то, и другое (typealias для Decodable & Encodable).

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

Декодирование (JSON → объект):


Используем JSONDecoder:

let json = """
{
"name": "Иван",
"age": 30
}
"""

guard let jsonData = json.data(using: .utf8) else { return }

do {
let user = try JSONDecoder().decode(User.self, from: jsonData)
print(user.name) // "Иван"
} catch {
print("Ошибка: \(error)")
}


Особенности:

  • Имена свойств должны совпадать с ключами JSON (или использовать CodingKeys).

  • Типы данных должны соответствовать.

Кодирование (объект → JSON):


Используем JSONEncoder:

let user = User(name: "Мария", age: 25)

do {
let jsonData = try JSONEncoder().encode(user)
let jsonString = String(data: jsonData, encoding: .utf8)
print(jsonString ?? "")
// {"name":"Мария","age":25}
} catch {
print("Ошибка: \(error)")
}


Настройки:

let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted // Красивый вывод
encoder.dateEncodingStrategy = .iso8601 // Формат даты

Кастомные ключи (CodingKeys):


Если имена в JSON не совпадают со свойствами:

struct Product: Codable {
var productName: String
var price: Double

enum CodingKeys: String, CodingKey {
case productName = "product_name_title"
case price
}
}

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


JSON:

{
"user": {
"name": "Анна",
"age": 28
}
}


Swift:

struct Response: Codable {
var user: User
}

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

Обработка опциональных значений:


struct Profile: Codable {
var name: String
var bio: String? // Опциональное поле
}


Если поля нет в JSON, свойство получит значение nil.

Игнорирование полей:


Пропускаем ненужные свойства:

struct Settings: Codable {
var theme: String
var fontSize: Int

// Не включаем в Codable
var temporaryFlag: Bool = false
}

Ручная реализация:


Для сложных случаев можно реализовать методы вручную:

struct Custom: Codable {
var id: UUID
var tags: [String]

init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(UUID.self, forKey: .id)
tags = try container.decode([String].self, forKey: .tags)
}

func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(tags, forKey: .tags)
}
}

Вывод:


  • Используйте Codable для большинства задач.

  • Настраивайте сложные случаи через CodingKeys.

  • Для нестандартных форматов реализуйте методы вручную.


Теперь вы легко сможете работать с любым JSON в Swift!
23.07.2025 23 406