Работа с JSON в Swift: парсинг и сериализация для начинающих

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Работа с JSON в Swift: парсинг и сериализация для начинающих

JSON (JavaScript Object Notation) — это самый популярный формат обмена данными в современных мобильных и веб-приложениях. Если вы разрабатываете под iOS или macOS на Swift, умение парсить и сериализовать JSON — обязательный навык. В этой статье мы разберем все основные способы работы с JSON: от классического JSONSerialization до современного протокола Codable. Материал ориентирован на начинающих разработчиков, которые уже знакомы с основами Swift.

Что такое JSON и зачем он нужен в Swift?

JSON — это текстовый формат, основанный на синтаксисе JavaScript. Он представляет собой пары "ключ-значение", вложенные объекты и массивы. В iOS-разработке JSON используется для:

  • Получения данных с REST API серверов
  • Сохранения конфигураций и настроек приложения
  • Обмена данными между модулями приложения
  • Работы с базами данных (например, Firebase или CoreData + JSON)

В Swift есть два основных подхода к работе с JSON: старый способ через JSONSerialization (из Foundation) и современный — с помощью протоколов Codable, Encodable и Decodable. Мы начнем с более простого JSONSerialization, чтобы понять механику, а затем перейдем к мощному Codable.

Парсинг JSON с помощью JSONSerialization (Foundation)

JSONSerialization — это встроенный в Foundation класс, который преобразует JSON-данные в объекты Swift (словари и массивы). Этот метод существует с первых версий Swift и до сих пор используется в легаси-проектах. Давайте разберем пример.

Предположим, у нас есть JSON-строка с информацией о пользователе:

let jsonString = """
{
    "name": "Иван",
    "age": 30,
    "email": "ivan@example.com",
    "isActive": true,
    "hobbies": ["чтение", "программирование", "спорт"]
}
"""

Чтобы распарсить этот JSON, мы сначала преобразуем строку в данные Data, а затем используем JSONSerialization:

import Foundation

if let jsonData = jsonString.data(using: .utf8) {
    do {
        if let dictionary = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] {
            print("Имя: \(dictionary["name"] ?? "Нет данных")")
            print("Возраст: \(dictionary["age"] ?? "Нет данных")")
            if let hobbies = dictionary["hobbies"] as? [String] {
                print("Хобби: \(hobbies.joined(separator: ", "))")
            }
        }
    } catch {
        print("Ошибка парсинга JSON: \(error.localizedDescription)")
    }
}

Важные моменты:

  • Всегда используйте try-catch — парсинг может выбросить ошибку.
  • Результат приходит как Any, поэтому нужно приводить к конкретному типу ([String: Any] для объекта, [Any] для массива).
  • Опции .mutableContainers и .fragmentsAllowed позволяют управлять гибкостью парсинга.

Современный подход: протокол Codable

Начиная с Swift 4, Apple представила протокол Codable (объединяет Encodable и Decodable). Это настоящая "магия" — достаточно объявить структуру, и Swift сам знает, как парсить и сериализовать данные. Давайте перепишем предыдущий пример с использованием Codable.

1. Объявление модели данных

struct User: Codable {
    let name: String
    let age: Int
    let email: String
    let isActive: Bool
    let hobbies: [String]
}

Обратите внимание: названия полей в структуре должны совпадать с ключами JSON (регистр важен). Если ключи отличаются (например, snake_case), используйте CodingKeys.

2. Парсинг JSON в объект Swift

let jsonData = jsonString.data(using: .utf8)!
let decoder = JSONDecoder()

do {
    let user = try decoder.decode(User.self, from: jsonData)
    print("Пользователь: \(user.name), \(user.age) лет")
    print("Активен: \(user.isActive)")
    print("Хобби: \(user.hobbies)")
} catch {
    print("Ошибка декодирования: \(error)")
}

Код стал гораздо чище! Вам не нужно вручную извлекать значения из словаря — все преобразования выполняются автоматически.

3. Сериализация (Swift → JSON)

Обратная операция — преобразование объекта Swift в JSON — выполняется с помощью JSONEncoder:

let newUser = User(
    name: "Мария",
    age: 25,
    email: "maria@example.com",
    isActive: false,
    hobbies: ["рисование", "путешествия"]
)

let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted // для красивого вывода

do {
    let encodedData = try encoder.encode(newUser)
    if let jsonStringOutput = String(data: encodedData, encoding: .utf8) {
        print(jsonStringOutput)
    }
} catch {
    print("Ошибка кодирования: \(error)")
}

Результат будет выглядеть так:

{
  "name" : "Мария",
  "age" : 25,
  "email" : "maria@example.com",
  "isActive" : false,
  "hobbies" : ["рисование", "путешествия"]
}

Продвинутые техники: кастомные ключи и вложенные объекты

В реальных проектах JSON часто приходит с сервера в snake_case (например, first_name), а в Swift принято использовать camelCase (firstName). Для этого используется перечисление CodingKeys и стратегия преобразования ключей.

Использование CodingKeys

struct UserProfile: Codable {
    let firstName: String
    let lastName: String
    let dateOfBirth: String

    enum CodingKeys: String, CodingKey {
        case firstName = "first_name"
        case lastName = "last_name"
        case dateOfBirth = "date_of_birth"
    }
}

Теперь структура будет правильно маппить JSON с сервера.

Автоматическое преобразование snake_case

Если у вас много полей, проще задать глобальную страте

Блоги

Рекомендаций по книгам