JSON обработка в Swift (iOS/macOS): от основ до продвинутого использования
JSON (JavaScript Object Notation) — один из самых популярных форматов обмена данными в мобильной и десктопной разработке. В экосистеме Swift (iOS/macOS) работа с JSON реализована нативно и элегантно, начиная с протокола Codable (Swift 4+) и заканчивая низкоуровневым JSONSerialization из Foundation. В этой статье мы разберём все ключевые подходы, покажем примеры кода и дадим практические рекомендации для образовательного сайта pythonlib.ru.
1. Основы: протокол Codable
Протокол Codable — это комбинация Encodable и Decodable. Он автоматически генерирует код для преобразования ваших структур и классов в JSON и обратно. Это основной и рекомендуемый способ работы с JSON в современном Swift.
1.1. Простая модель данных
import Foundation
struct User: Codable {
let id: Int
let name: String
let email: String
let isActive: Bool
}
// Пример JSON строки
let jsonString = """
{
"id": 1,
"name": "Иван Петров",
"email": "ivan@example.com",
"isActive": true
}
"""
// Декодирование
if let jsonData = jsonString.data(using: .utf8) {
let decoder = JSONDecoder()
if let user = try? decoder.decode(User.self, from: jsonData) {
print("Пользователь: \(user.name), email: \(user.email)")
}
}
1.2. Кастомные ключи (CodingKeys)
Если ключи в JSON отличаются от свойств модели (например, snake_case в JSON, camelCase в Swift), используйте перечисление CodingKeys:
struct Product: Codable {
let productId: Int
let productName: String
let price: Double
enum CodingKeys: String, CodingKey {
case productId = "product_id"
case productName = "product_name"
case price
}
}
let jsonProduct = """
{
"product_id": 101,
"product_name": "MacBook Pro",
"price": 2499.99
}
"""
2. Работа с массивами и вложенными объектами
JSON часто содержит массивы объектов или вложенные структуры. Codable справляется с этим без труда:
struct Author: Codable {
let name: String
let books: [Book]
}
struct Book: Codable {
let title: String
let year: Int
}
let jsonLibrary = """
{
"name": "Джоан Роулинг",
"books": [
{"title": "Гарри Поттер и философский камень", "year": 1997},
{"title": "Гарри Поттер и Тайная комната", "year": 1998}
]
}
"""
if let data = jsonLibrary.data(using: .utf8) {
let author = try? JSONDecoder().decode(Author.self, from: data)
print("Автор: \(author?.name ?? ""), книг: \(author?.books.count ?? 0)")
}
3. JSONSerialization — низкоуровневый подход
Хотя Codable — предпочтительный способ, иногда нужно работать с динамическими или неструктурированными данными. В таких случаях используйте JSONSerialization из Foundation:
let jsonString = """
{
"status": "success",
"data": {
"temperature": 22.5,
"humidity": 65,
"city": "Москва"
}
}
"""
if let data = jsonString.data(using: .utf8) {
do {
if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
if let status = json["status"] as? String {
print("Статус: \(status)")
}
if let dataDict = json["data"] as? [String: Any],
let temp = dataDict["temperature"] as? Double {
print("Температура: \(temp)°C")
}
}
} catch {
print("Ошибка парсинга JSON: \(error.localizedDescription)")
}
}
4. Обработка ошибок и опциональные значения
Реальные JSON-данные часто содержат отсутствующие поля или null. В Swift это обрабатывается через опциональные свойства (?) и механизм try/catch:
struct Response: Codable {
let code: Int
let message: String?
let data: UserData?
}
struct UserData: Codable {
let id: Int
let nickname: String?
}
let jsonWithNull = """
{
"code": 200,
"message": null,
"data": {
"id": 42,
"nickname": null
}
}
"""
do {
let response = try JSONDecoder().decode(Response.self, from: Data(jsonWithNull.utf8))
print("Код: \(response.code), никнейм: \(response.data?.nickname ?? "не указан")")
} catch {
print("Ошибка декодирования: \( Также в библиотеке
nlohmann/json для C++: полное руководство с примерами
Timber для Kotlin: полное руководство с примерами
Создание CLI-инструментов на Node.js: обзор фреймворков Commander, Yargs и Inquirer
Логирование в Go (Golang): лучшие библиотеки и решения для продакшена