Procesamiento de JSON en Swift (iOS/macOS): desde lo básico hasta el uso avanzado
JSON (JavaScript Object Notation) es uno de los formatos de intercambio de datos más populares en el desarrollo móvil y de escritorio. En el ecosistema de Swift (iOS/macOS), el trabajo con JSON se implementa de forma nativa y elegante, desde el protocolo Codable (Swift 4+) hasta el de bajo nivel JSONSerialization de Foundation. En este artículo, analizaremos todos los enfoques clave, mostraremos ejemplos de código y brindaremos recomendaciones prácticas para el sitio educativo pythonlib.ru.
1. Fundamentos: el protocolo Codable
El protocolo Codable es una combinación de Encodable y Decodable. Genera automáticamente código para convertir sus estructuras y clases a JSON y viceversa. Esta es la forma principal y recomendada de trabajar con JSON en Swift moderno.
1.1. Modelo de datos simple
import Foundation
struct User: Codable { let id: Int let name: String let email: String let isActive: Bool}
// Ejemplo de cadena JSONlet jsonString = """{ "id": 1, "name": "Iván Petrov", "email": "ivan@example.com", "isActive": true}"""
// Decodificaciónif let jsonData = jsonString.data(using: .utf8) { let decoder = JSONDecoder() if let user = try? decoder.decode(User.self, from: jsonData) { print("Usuario: \\(user.name), email: \\(user.email)") }}1.2. Claves personalizadas (CodingKeys)
Si las claves en JSON difieren de las propiedades del modelo (por ejemplo, snake_case en JSON, camelCase en Swift), use la enumeración 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. Trabajo con arreglos y objetos anidados
JSON a menudo contiene arreglos de objetos o estructuras anidadas. Codable maneja esto sin problemas:
struct Author: Codable { let name: String let books: [Book]}
struct Book: Codable { let title: String let year: Int}
let jsonLibrary = """{ "name": "Joanne Rowling", "books": [ {"title": "Harry Potter y la piedra filosofal", "year": 1997}, {"title": "Harry Potter y la cámara secreta", "year": 1998} ]}"""
if let data = jsonLibrary.data(using: .utf8) { let author = try? JSONDecoder().decode(Author.self, from: data) print("Autor: \\(author?.name ?? ""), libros: \\(author?.books.count ?? 0)")}3. JSONSerialization — enfoque de bajo nivel
Aunque Codable es la forma preferida, a veces es necesario trabajar con datos dinámicos o no estructurados. En tales casos, use JSONSerialization de Foundation:
let jsonString = """{ "status": "success", "data": { "temperature": 22.5, "humidity": 65, "city": "Moscú" }}"""
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("Estado: \\(status)") } if let dataDict = json["data"] as? [String: Any], let temp = dataDict["temperature"] as? Double { print("Temperatura: \\(temp)°C") } } } catch { print("Error al analizar JSON: \\(error.localizedDescription)") }}4. Manejo de errores y valores opcionales
Los datos JSON reales