Home » Guías » Trabajando con JSON en Swift 3
JSON Swift 3

Trabajando con JSON en Swift 3

JSON o Javascript Object Notation. Notación de objetos Javascript, que denota claramente cuál es su procedencia. Es un estándar de intercambio de datos ligero, subconjunto de la notación literal de objetos en Javascript. Hoy día, es uno de los formatos más usados en internet, junto a XML (el otro estándar más usado de intercambio de datos).

Su notación se construye con llaves y corchetes, así como el uso del símbolo de dos puntos para separar clave de dato como se haría en un tipo diccionario en Swift. Los datos de tipo cadena (entre ellos las claves) se acotan por dobles comillas.

En un ejemplo como el que nos dan en la Wikipedia interpretaríamos los datos de la siguiente forma:

Este ejemplo sería único diccionario de clave menu que dentro tendría como valor otro diccionario con varios valores clave: id, value y popup. Dentro de popup el dato sería otro diccionario más de clave menuitem cuyo dato es un array (por eso empieza con corchete) que tendría tres registros de diccionario con dos claves: value y onclick. Si lo comparamos en cuanto a posibilidades de representación es muy parecido a un plist, del que ya hablamos no hace mucho.

En otra estructura de datos, como la que uso en uno de los ejemplos que creamos en Apple Coding Academy con los alumnos, esa estructura sería la siguiente:

Este caso sería un array de diccionarios. Si nos fijamos, tenemos un tipo id que es numérico y no está entre dobles comillas. Además, en la propia notación dentro de las cadenas se usa el carácter de escape \ para anteceder las barras convencionales / por lo que en realidad debemos leer solo la barra normal.

Entendiendo la estructura del JSON

Antes de ponernos a cargar tenemos que tener clara una cosa: lo que se cargará ha de ser convertido a un tipo de dato acorde a lo que estamos leyendo en el JSON. Cuando cargamos el JSON, este se carga con un tipo Data que representa en Swift los datos en bruto. Y luego hay que pasarlo por un serializador, que lo lee, interpreta y convierte en algo que el lenguaje pueda interpretar. En el último caso visto, que teníamos un array en primer nivel porque este comienza con un corchete, tendríamos que hacer un as? [[String:Any]] donde los primeros corchetes representan el array y los segundos el diccionario que será cargado, donde la clave siempre es una cadena String y el dato, como puede ser cualquiera, se carga a través del protocolo Any donde cabe cualquier cosa en el lenguaje a título de clasificación.

En el caso expuesto al principio, donde tenemos un JSON que comienza por llaves, el casting tendría que ser a as? [String:Any] simplemente porque estamos cargando un diccionario. Y luego tener presente que dentro de ese Any estarán el resto de estructuras que igualmente tendremos que convertir a los tipos apropiados. Si recuperamos menu dentro tendremos un tipo String como dato en las claves id y value, pero en popup tendríamos un [String:[[String:Any]]], es decir, un diccionario cuya clave es una cadena y cuyo dato o valor es un array de un diccionario de tipo [String:Any]. Nótese que los primeros corchetes acotan el diccionario y los segundos definen el array donde están contenidos, al igual que sucede con la representación en JSON.

Serializando en Swift

Vamos a suponer que arrastramos el fichero JSON a nuestro Bundle del proyecto. Hecho esto, tendríamos que acceder al Bundle para obtener la ruta, luego añadirle el nombre de fichero y su extensión y cargar los datos para que entren en modo Data a nuestro programa. Vamos a suponer que cargamos el JSON del ejemplo de Apple Coding Academy que es un array de diccionarios [String:Any]. Los enlaces opcionales anidados que harían todo el proceso serían los siguientes:

Y ahí tenemos la clave: la clase JSONSerialization que es la que se encarga de coger los datos de tipo Data y convertirlos en el tipo que con el que vamos a trabajar, nativo de Swift. Ahora, dentro de ese if let ya tenemos el diccionario disponible para trabajar con el contenido del JSON. Aunque no hay que olvidar que es un [String:Any] y eso implica que al extraer cualquier dato habrá que convertirlo al tipo adecuado (en la mayoría de los casos es un String). De hecho, si en todos los casos nuestro JSON tiene datos String podríamos declarar el diccionario [String:String].

Grabando en disco

Los JSON también podemos grabarlos en el directorio de documentos, con el fin de grabar la información si queremos. Solo hay que extraer la ruta de documentos del sistema.

Lo primero que hacemos es usar el método data de JSONSerialization que devuelve un tipo de dato Data que luego podemos grabar a disco. Al método data solo hay que pasarle el diccionario que queremos pasar a JSON y en options podemos invocar el modificar .prettyPrinted que se encargará de generar el JSON de una forma que sea fácil de ver si accedemos a su contenido.

Por último solo tenemos que recuperar la carpeta de documentos, añadirle el nombre de fichero que queremos grabar y usar el método write que tienen todos los tipos Data que permiten grabar su contenido en una ruta que le pasemos.

JSON a través de la red

El tipo Data que hemos leído del Bundle también puede leerse desde internet ya que todo lo que leemos de la web se lee igualmente como tipo Data. Basta usar esta sencilla función:

Nada más simple: llamamos a URLSession.shared creando una tarea de datos unida a una URL e invocamos con el método resume() para que se ejecute. Tras esto, el closure que enviamos a la tarea para cuando esta termine se encarga de construir el JSON igual que ya lo hicimos al leerlo de disco. Complicación nula.

Un formato potente

Como podemos ver, es un formato ligero de datos y potente, para el que Swift está preparado en uso y trabajo con él de una manera muy eficiente. Probad y contadnos qué tal vuestra experiencia. Un saludo y Good Apple Coding.

Acerca de Julio César Fernández

Analista, consultor y periodista tecnológico, desarrollador, empresario, productor audiovisual, actor de doblaje e ingeniero de vídeo y audio.

Otras recomendaciones

Codable (I)

Codable (I), cargando un JSON hacia un struct

Aprendemos a cómo cargar el contenido de un archivo JSON directamente en instancias de tipo struct con el nuevo protocolo Codable y la serialización de Swift 4. Un proceso no solo simple, sencillo y potente, si no que nos evita tener que usar diccionario, sabernos claves de memoria... simplemente cargamos el JSON, parseamos y listo. Magia Swift 4.