Tutorial Codables Swift 4 – God Level

Si ya has leído el primer artículo de codables sabrás como usar los codables de forma simple. Pero este protocolo de Swift 4 tiene muchísima más potencia y complejidad que podemos aplicar para todos los casos de uso.

Para usar toda la potencia de los codables deberemos sobre escribir sus métodos e inicializadores.

Vamos a ver varios casos complejos en los que implementar este protocolo.

Codables como tipo

Hasta ahora hemos visto que los codables se usan para mapear JSON. y que las clases o struct que implementan el protocolo se corresponden con un JSON y los atributos del objeto deben coincidir con los del JSON. En este caso vamos a asignar nuestros propios tipos como si de un Int o un String se tratara.

Esto nos puede ser muy útil por ejemplo si en los servicios nos llegan las fechas como time stamp y nosotros en la app queremos usar Date. En este caso guardaremos el valor como time stamp pero lo asignamos a un objeto del tipo DateModel.

JSON:


Type:

Clase final:

Lo primero que vemos es que estamos usando los métodos e inits de Encodable y Decodable. Una cosa curiosa del init es esta línea:

Lo que estamos haciendo ahí es sacar un contenedor de un único valor, lo que quiere decir que este codable solo va a tener una propiedad. En este caso una propiedad privada timeStamp.

Con este tipo de codable no nos hace falta el CodingKey para asignar nombres ya que solo habrá un tipo, así que en la siguiente línea asignaremos a nuestra propiedad timeStamp el único valor que hay dentro del contenedor.

Con esto ya tenemos el protocolo Decodable terminado pero tenemos que terminar también Encodable para que se cumpla el protocolo Codable.

Para ello escribimos la función encode que también es muy sencilla. Solo le diremos que cree un contenedor único mediante la línea

y que le asigne al contenedor el valor de timeStamp.

Y ya con eso hemos terminado. Como podemos ver timeStamp es una variable privada ya que solo trabajaremos con la propiedad date que no es más que una propiedad que convierte el valor de timeStamp a Date para que sea comprensible en la app y que cuando se asigna convierte el valor de un Date a timeStamp.

Custom Codable

Hay muchas veces que el desarrollador de back recibe una iluminación y decide separar los objetos con un montón de saltos en el JSON. Algo así:

Si algún desarrollador de back manda algo así… Pero… puede pasar y nosotros no nos podemos dejar intimidar. Para eso los codables ofrecen una solución para abstraernos en el código de este tipo de personas. Lo primero es escribir la base de nuestro objeto que quedaría así:

Ahora tenemos que escribir varios enums con los CodingKey de cada salto. Para hacerlo de forma ordenada lo sacamos a una extensión.

Con esto lo que haremos será sacar del decoder un contenedor para cada salto. Ahora vamos a por el init. Pongo como queda y luego explico línea a línea.

Primero extraemos el contenedor base que tendrá como propiedades “data”,”Other_Data” y “address”. Para eso usamos la línea:

En la que hacemos referencia al enum BaseContainer. Luego lo primero que hacemos es extraer el valor para la propiedad “address” del contenedor base.

Luego le decimos al contenedor que de sus propiedades nos saque el siguiente contenedor que se corresponderá con el enum DataContainer y que se llama “data”

De “dataContainer” extraeremos los valores para “name” y “age” y luego seguiremos los mismos pasos para el contenedor OtherDataContainer.

Desgraciadamente, para guardar nuestros datos debemos reformatearlos de la misma forma que vienen del servicio para que el init y el encoder se entiendan y para que el dev de back que pretende arruinarnos el día reciba correctamente su JSON infernal. Para ello volvemos a formar los contenedores y a hacer el encode.

Lo que hacemos aquí es volver a encapsular toda la información dentro de la maraña de JSON de nuestro backend.

Conclusión

Los codables es una herramienta que debemos saber usar a la perfección ya que como vemos tiene mucha potencia y nos vale para casi todos los casos de uso. Para lo único que no se pueden usar codables por ejemplo es para struct o clases genéricas. Para ese tipo de parseo deberemos hacerlo manual. Pero para el resto si que podemos usar el protocolo Codable y ya dependerá del caso si lo haremos de forma sencilla o más compleja.

¡¡Aún hay más!!

Nos puede pasar que estemos intentando hacer un decode de una colección (array) de objetos y que en dichos objetos surja algún dato erróneo o inconsistente. Esto pasa sobre todo con aplicaciones que acaban de realizar una migración de datos o que tienen ya muchas versiones y los datos pueden venir de versiones muy antiguas.

El problema que tiene el protocolo codable para estos casos es que si falla el decoder de un único objeto dentro de un array falla todo el decode. Pero Apple confía en que sus desarrolladores saben usar toda la potencia de Swift y sabrán buscarle la vuelta a este inconveniente. ¡Efectivamente!

A este arreglo le e dado el nombre de Decodable+Failable.swift

Lo primero es un struct genérico que tratará los errores en el decoder y devolverá nil. Tan sencillo como esto:

Después de lo anterior ya debemos saber que significa cada línea.

Ahora haremos una extensión a Array donde el elemento cumpla el protocolo Decodable que quedaría así:

Lo que hacemos primero es declarar un enum para nuestro error (Yo soy de objc y prácticamente no trato los errores en Swift pero si alguien los trata puede hacer el error más descriptivo).

Luego declaramos una función estática a la que le pasamos un data y devuelve un array de elementos. Lo que hacemos aquí es sencillo (Línea a línea).

  • Si data es nil tiramos un error
  • Hacemos un decode de un array de objetos failable con el elemento del array
  • Sacamos a un nuevo array todos los elementos de failable que no sean nil. Para ello usamos compactMap
  • Devolvemos un nuevo array con los elementos que se han podido decodificar correctamente.

Dejo aquí el fichero Decodable+Failable.swift

Por: Álvaro Royo

Álvaro Royo

 

iOS Senior Developer | Instructor de “Superpoderes iOS” en el Bootcamp Desarrollo Mobile de KeepCoding

Si tienes algo que deseas compartir o quieres formar parte de JustCodeIt, escríbenos a [email protected]



Share this:

Leave a comment