Trabajo con JSON en Swift: análisis y serialización
JSON (JavaScript Object Notation) es un formato ligero de intercambio de datos, ampliamente utilizado en servicios web y aplicaciones móviles. En el ecosistema de Apple (iOS, macOS, watchOS, tvOS), el trabajo con JSON es una parte integral del desarrollo: desde la carga de datos desde el servidor hasta el guardado de configuraciones de la aplicación. En este artículo, veremos en detalle cómo realizar el análisis (decodificación) y la serialización (codificación) de JSON en Swift, utilizando los protocolos incorporados Codable, JSONDecoder y JSONEncoder.
1. Fundamentos de Codable: modelo de datos
El enfoque moderno para trabajar con JSON en Swift se basa en el protocolo Codable, que combina dos protocolos: Encodable (para serialización) y Decodable (para análisis). Para que su estructura o clase pueda convertirse a JSON y viceversa, basta con declararla como Codable.
Consideremos un ejemplo de modelo de usuario:
struct User: Codable { let id: Int let name: String let email: String let isActive: Bool}Si las claves en JSON difieren de los nombres de las propiedades en Swift (por ejemplo, se usa snake_case en lugar de camelCase), puede usar la enumeración CodingKeys:
struct User: Codable { let id: Int let fullName: String let email: String let isActive: Bool
enum CodingKeys: String, CodingKey { case id case fullName = "full_name" case email case isActive = "is_active" }}2. Análisis de JSON con JSONDecoder
Para convertir una cadena JSON o datos en objetos Swift se utiliza JSONDecoder. El método principal es decode(_:from:), que recibe el tipo de datos (que cumple con Decodable) y un objeto Data.
Ejemplo de análisis de una cadena JSON obtenida de una API:
let jsonString = """{ "id": 1, "name": "Iván Petrov", "email": "ivan@example.com", "is_active": true}"""
let jsonData = Data(jsonString.utf8)
do { let decoder = JSONDecoder() let user = try decoder.decode(User.self, from: jsonData) print("Usuario: \\(user.name), email: \\(user.email)")} catch { print("Error de decodificación: \\(error.localizedDescription)")}A menudo, JSON llega como un array de objetos. En este caso, simplemente especifique el tipo [User].self:
let jsonArrayString = """[ {"id": 1, "name": "Iván", "email": "ivan@test.com", "is_active": true}, {"id": 2, "name": "María", "email": "maria@test.com", "is_active": false}]"""
let jsonArrayData = Data(jsonArrayString.utf8)
do { let users = try JSONDecoder().decode([User].self, from: jsonArrayData) users.forEach { print($0.name) }} catch { print("Error: \\(error)")}3. Serialización de objetos a JSON con JSONEncoder
El proceso inverso — convertir un objeto Swift a JSON — se realiza con JSONEncoder. El método encode(_:) devuelve un objeto Data, que luego se puede convertir a una cadena o enviar al servidor.
let user = User(id: 3, fullName: "Alexéi Smirnov", email: "alex@example.com", isActive: true)
do { let encoder = JSONEncoder() encoder.outputFormatting = .prettyPrinted // para formato legible let jsonData = try encoder.encode(user) if let jsonString = String(data: jsonData, encoding: .utf8) { print(jsonString) }} catch { print("Error de codificación: \\(error)")}La salida se verá así:
{ "id" : 3, "full_name" : "Alexéi Smirnov", "email" : "alex@example.com", "is_active" : true}Tenga en cuenta que el JSO