JSONSerialization: что это, методы класса Foundation и как работает

Автор: IT Sectr Опубликовано: 2026-03-15 Время чтения: 8 мин

JSONSerialisation — встроенный класс 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 остаётся востребованным в legacy-проектах на 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 parse error: \(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("Product: \(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("User: \(name) (ID: \(userId))")

    } catch let error as ParsingError {
        print("Parse failed: \(error)")
    } catch {
        print("Unexpected error: \(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 with \(dictionary.count) keys")
        } else if let array = object as? [Any] {
            print("Array with \(array.count) items")
        }

    } catch CocoaError.propertyListReadCorrupt {
        print("Corrupt JSON data")
    } catch let error as CocoaError {
        print("Cocoa error: \(error)")
    } catch {
        print("Unknown error: \(error)")
    }
}

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

На производительность 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 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

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