Serialización de objetos en Swift (iOS/macOS): Codable, JSON y PropertyList

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Serialización de objetos en Swift (iOS/macOS): Codable, JSON y PropertyList



La serialización es el proceso de convertir objetos de datos en un formato adecuado para almacenamiento o transmisión (por ejemplo, JSON, XML, Property List). En el ecosistema de Apple (iOS, macOS, watchOS, tvOS), Swift proporciona un mecanismo potente y elegante para la serialización y deserialización: el protocolo Codable. En este artículo, analizaremos en detalle cómo usar Codable, JSONEncoder, PropertyListEncoder y sus análogos para trabajar con datos.



¿Qué es Codable?

Codable es un protocolo compuesto que combina Encodable (para codificar un objeto a un formato externo) y Decodable (para decodificar desde un formato externo a un objeto). Si su estructura o clase Swift cumple con Codable, automáticamente obtiene la capacidad de serializarla y deserializarla.



Declaración básica:

struct User: Codable {    let id: Int    let name: String    let email: String}


Todos los tipos estándar de Swift (String, Int, Double, Bool, Date, Data, URL e incluso tipos opcionales y arreglos/diccionarios) ya cumplen con Codable.



Codificación a JSON

Para codificar un objeto a JSON se utiliza JSONEncoder. Ejemplo:

let user = User(id: 1, name: "Iván Petrov", email: "ivan@example.com")let encoder = JSONEncoder()encoder.outputFormatting = .prettyPrinted // para una salida bonita

do { let jsonData = try encoder.encode(user) if let jsonString = String(data: jsonData, encoding: .utf8) { print(jsonString) }} catch { print("Error de codificación: \\(error)")}


Resultado:

{  "id" : 1,  "name" : "Iván Petrov",  "email" : "ivan@example.com"}


Decodificación desde JSON

Para la transformación inversa se utiliza JSONDecoder:

let jsonString = """{  "id": 2,  "name": "María Sidorova",  "email": "maria@example.com"}"""let jsonData = Data(jsonString.utf8)let decoder = JSONDecoder()

do { let decodedUser = try decoder.decode(User.self, from: jsonData) print("Usuario decodificado: \\(decodedUser.name)")} catch { print("Error de decodificación: \\(error)")}


Trabajo con Property List (plist)

Para la serialización al formato XML Property List se utilizan PropertyListEncoder y PropertyListDecoder. Esto es útil para almacenar datos en archivos de configuración o UserDefaults.



// Codificación a plistlet encoder = PropertyListEncoder()encoder.outputFormat = .xml

do { let plistData = try encoder.encode(user) // plistData se puede guardar en un archivo o en UserDefaults} catch { print("Error de codificación plist: \\(error)")}

// Decodificación desde plistlet decoder = PropertyListDecoder()do { let decodedUser = try decoder.decode(User.self, from: plistData) print(decodedUser)} catch { print("Error de decodificación plist: \\(error)")}


Claves personalizadas (CodingKeys)

A veces los nombres de las propiedades en Swift no coinciden con las claves en JSON. Para esto se utiliza 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 }}


Ahora el JSON con las claves product_id y product_name será procesado correctamente.



Manejo de fechas y otros tipos especiales

Por defecto, JSONEncoder y JSONDecoder codifican las fechas como TimeInterval

Recommendations