JSONSerialization: що це, методи класу Foundation та як працює

Автор: IT Sectr Опубліковано: 2026-03-15 Час читання: 8 хв

JSONSerialization — вбудований клас iOS з фреймворку Foundation, призначений для перетворення JSON в об’єкти Foundation і навпаки. Цей API є базовим механізмом роботи з JSON на платформах Apple без підключення сторонніх бібліотек, підтримуючи парсинг словників, масивів та примітивних типів. За даними Apple Developer, 2024, JSONSerialization підтримує роботу з Data, потоками та опціями читання для гнучкого оброблення даних JSON.

Головне

  • JSONSerialization — вбудований клас Foundation для парсингу JSON на iOS та macOS
  • jsonObject — метод перетворення JSON Data в словники та масиви Foundation
  • data — метод серіалізації об’єктів Foundation назад в JSON Data
  • isValidJSONObject — перевірка, чи можна серіалізувати об’єкт в JSON
  • Codable — сучасна альтернатива з типізованою серіалізацією в Swift

Що таке JSONSerialization

JSONSerialization — це клас з фреймворку Foundation, доступний на iOS, macOS, tvOS та watchOS. Він надає методи для перетворення JSON Data в об’єкти Foundation (NSDictionary, NSArray, NSString, NSNumber) та навпаки. Клас з’явився в iOS 5 і до введення Codable (Swift 4) залишався основним способом роботи з JSON на платформах Apple. Незважаючи на вік, JSONSerialization залишається запитуваним в застарілих проектах Objective-C та в сценаріях, де потрібна динамічна обробка JSON без фіксованої схеми моделі.

Коли використовується JSONSerialization

Незважаючи на появу Codable, JSONSerialization залишається актуальним в кількох сценаріях. Динамічна структура JSON — коли формат відповіді змінюється або невідомий заздалегідь — вимагає доступу до словників за ключами, що легкше зробити через JSONSerialization. Клас також використовується в проектах Objective-C, де Codable недоступний, та при роботі з потоками для покрокового парсингу великих JSON-файлів. У тестах та макетах isValidJSONObject та data(withJSONObject:options:) дозволяють швидко генерувати JSON фікстури без сторонніх бібліотек, прискорюючи розробку та прототипування.

swift
import Foundation

// Базова структура використання JSONSerialization
let jsonString = """
{
    "id": 1,
    "name": "John Doe",
    "email": "john@example.com"
}
"""

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

do {
    let json = try JSONSerialization
        .jsonObject(with: jsonData,
                       options: .mutableContainers)
    print(json)
} catch {
    print("Помилка парсингу JSON: \(error)")
}

Основні методи класу

JSONSerialization надає чотири основні методи для роботи з JSON. Основний метод — jsonObject(with:options:), який перетворює Data в об’єкти Foundation. Метод data(withJSONObject:options:) виконує зворотну серіалізацію. isValidJSONObject(_:) перевіряє, чи можна серіалізувати об’єкт. writeJSONObject(_:to:options:error:) записує JSON безпосередньо в потік. Для читання JSON з InputStream існує метод jsonObject(with:options:), який приймає потік замість Data, що зручно при інтеграції з мережевими запитами, що повертають потокові дані.

JSONObject та JSONData

Метод jsonObject приймає Data та повертає Any — звичайно NSDictionary або NSArray. Для безпечного використання результат приводиться до очікуваного типу через умовне приведення. Метод data приймає об’єкт Foundation та повертає Data з JSON-представленням. Опція .prettyPrinted додає форматування з відступами для читабельності.

swift
let jsonString = """
{
    "products": [
        {"id": 1, "name": "iPhone", "price": 999},
        {"id": 2, "name": "iPad", "price": 799}
    ]
}
"""
let data = Data(jsonString.utf8)

if let json = try? JSONSerialization
    .jsonObject(with: data) as? [String: Any],
    let products = json["products"] as? [[String: Any]] {

    for product in products {
        if let name = product["name"] as? String {
            print("Продукт: \(name)")
        }
    }
}

// Зворотна серіалізація: об’єкт -> JSON
let outputDict: [String: Any] = ["status": "ok", "count": 42]
if let outputData = try? JSONSerialization
    .data(withJSONObject: outputDict,
                options: .prettyPrinted) {
    String(data: outputData, encoding: .utf8)
}

Приклади парсингу JSON

Базовий парсинг словника з примітивними типами — найпоширеніша операція з JSONSerialization. Після отримання Data через URLSession розробник викликає jsonObject та приводить результат до очікуваного типу. Для масивів об’єктів використовується приведення до [[String: Any]], після чого кожен елемент обробляється в циклі. Цей підхід гнучкий, але вимагає ручного керування типами.

Парсинг вкладених структур

Справжні API повертають складні вкладені JSON-об’єкти з масивами, датами та опціональними полями. JSONSerialization коректно обробляє будь-яку глибину вкладеності, але розробник повинен самостійно приводити кожен рівень до потрібного типу. Для спрощення цього завдання Apple рекомендує використовувати Codable для типізованих даних, а JSONSerialization — лише для динамічних структур.

swift
// Парсинг відповіді API
func parseUserResponse(data: Data) {
    do {
        guard let json = try JSONSerialization
            .jsonObject(with: data) as? [String: Any]
        else { return }

        guard let userId = json["id"] as? Int,
              let name = json["name"] as? String
        else {
            throw ParsingError.missingField
        }

        print("Користувач: \(name) (ID: \(userId))")

    } catch let error as ParsingError {
        print("Парсинг невдалий: \(error)")
    } catch {
        print("Несподівана помилка: \(error)")
    }
}

enum ParsingError: Error {
    case missingField
    case invalidType
}

Обробка помилок

JSONSerialization викидає помилки при недійсному JSON, невідповідності типів або перевищенні глибини вкладеності. Помилки належать до типу CocoaError та містять код з описом проблеми. Розробник повинен обробляти їх через конструкцію do-catch, інакше програма аварійно завершиться. Найпоширеніші помилки: NSPropertyListReadCorruptError (недійсний JSON) та NSPropertyListReadUnknownError. Кожен тип помилки потребує своєї стратегії обробки: при недійсному форматі запитати повторне відправлення даних, а при невідповідності структури оновити модель парсингу.

Типи помилок десеріалізації

Недійсний JSON — найпоширеніша причина збоїв: пропущена кома, зайвий символ або неекранована лапки ламають весь парсинг. Другий тип помилок — невідповідність очікуваній структурі: наприклад, сервер повернув масив замість словника. JSONSerialization.fragmentsAllowed дозволяє читати JSON, чиїм коренем є не словник або масив, а примітивне значення. Розробник також може зіткнутися з помилкою перевищення глибини вкладеності, коли JSON містить ззадто багато рівнів ієрархії.

Опції читання та запису

JSONSerialization надає кілька опцій для налаштування парсингу. .mutableContainers повертає NSMutableDictionary та NSMutableArray замість незмінних версій, що корисно при модифікації даних після парсингу. .mutableLeaves робить рядкові значення змінними. .fragmentsAllowed дозволяє JSON, чиїм коренем є не об’єкт або масив, а рядок або число — зручно для простих відповідей API. Опції .withoutEscapingSlashes та .sortedKeys доступні для методу data(withJSONObject:options:), керуючи форматуванням серіалізованого JSON. Опції передаються як бітова маска, що дозволяє комбінувати кілька значень через оператор | для гнучкого налаштування парсингу.

swift
// Обробка різних типів помилок
func safeParse(jsonData: Data) {
    do {
        let object = try JSONSerialization
            .jsonObject(with: jsonData,
                           options: .fragmentsAllowed)

        if let dictionary = object as? [String: Any] {
            print("Словник з \(dictionary.count) ключами")
        } else if let array = object as? [Any] {
            print("Масив з \(array.count) елементів")
        }

    } catch CocoaError.propertyListReadCorrupt {
        print("Пошкоджені дані JSON")
    } catch let error as CocoaError {
        print("Помилка Cocoa: \(error)")
    } catch {
        print("Невідома помилка: \(error)")
    }
}

// Перевірка валідності об’єкта перед серіалізацією
let testObject: [String: Any] = ["key": "value", "nested": ["a": 1]]
if JSONSerialization.isValidJSONObject(testObject) {
    print("Дійсний JSON-об’єкт")
}

Продуктивність JSONSerialization залежить від розміру даних та частоти викликів. Для одноразового парсингу малої відповіді сервера різниця непомітна, але при обробці десятків мегабайтів JSON або частих викликів у циклах варто враховувати накладні витрати на приведення типів. JSONSerialization працює синхронно в поточному потоці, тому для великих документів рекомендується виносити парсинг у фонову чергу через DispatchQueue.global(). Альтернативно можна використовувати InputStream для потокової обробки без завантаження всього файлу в пам'ять, що критично для програм з обмеженими ресурсами. Для запису JSON у файл або мережевий потік метод writeJSONObject(_:to:options:error:) дозволяє напряму відправляти серіалізовані дані в OutputStream без створення проміжного об’єкта Data, що знижує споживання пам'яті при роботі з великими документами.

Часті запитання

Що таке JSONSerialization в iOS?

JSONSerialization — це клас Foundation для перетворення JSON Data в об’єкти Foundation (NSDictionary, NSArray) та навпаки. Він працює на iOS, macOS, tvOS та watchOS без додаткових бібліотек.

Чим JSONSerialization відрізняється від Codable?

Codable — це протокол Swift для автоматичної типізованої серіалізації, який компілюється в типобезпечний код. JSONSerialization працює з динамічними типами Any та потребує ручного приведення. Codable краще для нових проектів, JSONSerialization — для Objective-C та динамічних даних.

Як обробити помилку парсингу JSON?

Використовуйте конструкцію do-catch при виклику jsonObject. Помилки JSONSerialization належать до CocoaError. Для налагодження перевірте NSPropertyListReadCorruptError, який вказує на недійсний формат даних JSON.

Чи підтримує JSONSerialization вкладені структури?

Так, JSONSerialization підтримує будь-яку глибину вкладеності словників та масивів. Усі вкладені об’єкти перетворюються в відповідні типи Foundation (NSDictionary, NSArray, NSString, NSNumber), зберігаючи первинну структуру JSON.

Коли використовувати JSONSerialization замість Codable?

JSONSerialization доречний для динамічних структур JSON, у проектах Objective-C, при роботі з потоками та для перевірки дійсності JSON через isValidJSONObject. Для типізованих структур з відомою схемою краще обрати Codable.

Підсумки

  • JSONSerialization — вбудований клас Foundation для базової роботи з JSON на платформах Apple
  • jsonObject — основний метод парсингу, що перетворює Data в словники та масиви Foundation
  • data — метод зворотної серіалізації об’єктів Foundation в JSON Data з опціями форматування
  • isValidJSONObject — предикат для перевірки, чи можна серіалізувати об’єкт в JSON
  • Обробка помилок обов’язкова через do-catch для запобігання аварійного завершення програми
  • Codable — сучасна типізована альтернатива для проектів Swift з відомою схемою даних

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також