Работа с JSON в Swift: парсинг и сериализация на практике

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

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

Начать курс

Работа с JSON в Swift: парсинг и сериализация на практике

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

Статья предназначена для разработчиков, которые уже знакомы с основами Swift и хотят уверенно работать с сетевыми запросами и локальным хранением данных в формате JSON.

1. Основы JSON и его место в Swift-приложениях

JSON представляет собой текстовый формат, основанный на двух структурах: объекты (набор пар ключ-значение) и массивы (упорядоченные списки). В Swift этим структурам соответствуют Dictionary и Array. Типы данных в JSON ограничены: строки, числа, булевы значения, null, объекты и массивы.

Типичный сценарий использования JSON в iOS/macOS приложении выглядит так:

  • Получение JSON-строки от сервера (через URLSession).
  • Парсинг JSON в модели Swift (например, структуры или классы).
  • Обработка данных и отображение их в интерфейсе.
  • Сериализация (обратное преобразование) моделей в JSON для отправки на сервер.

Apple предоставляет два основных подхода для работы с JSON: JSONSerialization (низкоуровневый, но гибкий) и Codable (высокоуровневый, типобезопасный, рекомендованный с Swift 4+).

2. Парсинг JSON с помощью Codable (рекомендуемый способ)

Протокол Codable объединяет Encodable (для сериализации) и Decodable (для парсинга). Это самый простой и безопасный способ работы с JSON в Swift.

Пример 1: Парсинг простого JSON-объекта

Допустим, сервер возвращает следующий JSON:

{
    "userId": 1,
    "id": 1,
    "title": "Пример задачи",
    "completed": false
}

Создадим структуру модели, соответствующую Codable:

struct TodoItem: Codable {
    let userId: Int
    let id: Int
    let title: String
    let completed: Bool
}

Теперь выполним парсинг JSON-строки:

let jsonString = """
{
    "userId": 1,
    "id": 1,
    "title": "Пример задачи",
    "completed": false
}
"""

if let jsonData = jsonString.data(using: .utf8) {
    let decoder = JSONDecoder()
    do {
        let todo = try decoder.decode(TodoItem.self, from: jsonData)
        print("Задача: \(todo.title), выполнена: \(todo.completed)")
    } catch {
        print("Ошибка парсинга: \(error.localizedDescription)")
    }
}

Пример 2: Парсинг массива объектов

Если сервер возвращает массив задач:

[
    {"userId": 1, "id": 1, "title": "Задача 1", "completed": false},
    {"userId": 1, "id": 2, "title": "Задача 2", "completed": true}
]

Парсинг выполняется так же просто — нужно указать тип массива:

let todoArray = try decoder.decode([TodoItem].self, from: jsonData)

2.1. Кастомные ключи и snake_case

Часто JSON использует формат snake_case (например, user_id), а в Swift принят camelCase (userId). JSONDecoder умеет преобразовывать ключи автоматически:

decoder.keyDecodingStrategy = .convertFromSnakeCase

Если нужно задать нестандартное соответствие, используйте перечисление CodingKeys:

struct User: Codable {
    let fullName: String
    let emailAddress: String

    enum CodingKeys: String, CodingKey {
        case fullName = "full_name"
        case emailAddress = "email_address"
    }
}

3. Сериализация объектов в JSON с помощью Codable

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

Пример: Сериализация структуры в JSON

let newTodo = TodoItem(userId: 1, id: 3, title: "Новая задача", completed: false)
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted // для читаемого вывода

do {
    let jsonData = try encoder.encode(newTodo)
    if let jsonString = String(data: jsonData, encoding: .utf8) {
        print(jsonString)
    }
} catch {
    print("Ошибка сериализации: \(error)")
}

Результат выполнения:

{
  "userId" : 1,
  "id" : 3,
  "title" : "Новая задача",
  "completed" : false
}

Для отправки на сервер JSON обычно передаётся как тело HTTP-запроса. Пример с URLSession:

var request = URLRequest(url: URL(string: "https://api.example.com/todos")!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try encoder.encode(newTodo)

let task = URLSession.shared.dataTask(with: request) { data, response, error in
    // обработка ответа
}
task.resume()

4. Работа с JSONSerialization (для сложных или динамических данных)

Несмотря на всю мощь Codable, иногда требуется обработать JSON с неизвестной структурой или смешанными типами. В таких случаях на помощь приходит JSONSerialization.

Пример: Парсинг с JSONSerialization

if let jsonData = jsonString.data(using: .utf8) {
    do {
        if let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] {
            // Работаем с Dictionary
            if let title = jsonObject["title"] as? String {
                print("Title: \(title)")
            }
        } else if let jsonArray = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [[String: Any]] {
            // Работаем с ма                

Блоги

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