Aprende a usar URLSession y Combine (decode, tryMap y map)
Podemos usar Combine con URLSession, de esta manera creamos un Publisher en el que podemos usar operadores y así transformar los valores que viajan en nuestro Publisher. En este caso utilizamos los operadores map, tryMap, y decode. Es un ejemplo muy práctico y real.
Tabla de contenido
Hoy en SwiftBeta vamos a aprender a cómo crear una petición HTTP usando Combine. Vas a ver lo sencillo y limpio que es realizar la petición HTTP y luego usar varios operadores de Combine para transformar el JSON obtenido a un modelo de nuestro dominio.
A lo largo de los videos del canal, hemos aprendido a realizar una petición HTTP de varias maneras, usando completionBlocks, async/await, promesas como vimos en el último video de la serie de Combine, etc. En el video de hoy vamos a usar directamente un Publisher de URLSession.
Creamos una nueva page en nuestro Playground
Antes de empezar con el nuevo video, vamos a crear una nueva Page en nuestro Playground. Si acabas de llegar al canal, por cada page que tenemos en nuestro Playground es un video que encontrarás en la serie de Combine. En este caso creamos una page llamada URLSession.
Una vez creada la Page, lo primero de todo que vamos hacer es importar Combine.
Antes de continuar, si quieres apoyar el contenido que subo cada semana, suscríbete. De esta manera seguiré publicando contenido completamente grautito en Youtube.
Ahora sí, vamos a continuar, lo siguiente que vamos hacer es buscar una URL donde queramos hacer una petición HTTP. En nuestro caso vamos a escoger una API que ya hemos usado en varios videos del canal, la API de Rick and Morty.
Es una API muy sencilla, podemos ir al siguiente enlace para obtener más información del endpoint que vamos a usar https://rickandmortyapi.com
Una vez aquí nos vamos a documentación, y escogemos este endpoint https://rickandmortyapi.com/api, fíjate que este método nos retorna un JSON muy sencillo, 3 keys con 3 valores. Una vez sabemos el endpoint al que vamos a llamar, lo siguiente que vamos hacer es crear el modelo de nuestro dominio, de esta manera podremos transformar el JSON a una struct, y esta struct es la siguiente:
Perfecto, lo siguiente que vamos hacer es realizar la petición HTTP. Creamos un tipo URL con el endpoint que vamos a usar https://rickandmortyapi.com/api
Y ahora es donde viene la parte interesante, vamos a usar URLSession, y en este caso usamos el método llamado dataTaskPublisher. Al añadir este método podemos escoger entre 2 opciones, una pasándole una URL y la otra pasándole un URLRequest. Escogemos la primera:
Al utilizar esta última línea, podemos trabajar como si de un Publisher se tratara, podemos concatenar diferentes operadores y manipular nuestro Publisher como hemos visto en los anteriores videos.
En este caso, al realizar la petición HTTP, vamos a usar el operador tryMap para inspeccionar el resultado ¿Por qué quiero hacer esto?
- En caso de obtener un status code que no sea igual a 200, voy a lanzar un error especifico. Este error lo quiero lanzar en mi código al hacer una comprobación que crearemos a en los próximos minutos.
- Y por otro lado, si todo va bien, retornamos el data de la petición HTTP
Al usar el operador tryMap, dentro del closure recibimos un data y un response de nuestra petición HTTP. Vamos a comprobar que el status code de la petición es 200 para publicar el data dentro del Publisher, y sino publicamos un error en nuestro Publisher de tipo URLError(.badServerResponse):
Si compilamos vemos que no obtenemos ningún error. Vamos a continuar. Si todo va bien y se publica el data dentro del Publisher, lo que vamos hacer es recogerlo usando otro operador llamado decode. Este operador nos va a servir para transforma el data a un modelo de nuestro dominio, y para ser más concretos a la Struct que hemos creado al inicio del video llamada DataModel:
Si compilamos, vemos que seguimos sin tener errores, para ver que todo funciona correctamente, vamos a retener nuestro subscriber asignándolo a una constante llamada cancellable:
Y ahora nos vamos a suscribir a nuestro Publisher, y ¿cómo lo hacemos? Pues de la misma manera que hemos visto en todos los anteriores videos de la serie de Combine, vamos a usar el método sink:
Si ahora compilamos, vamos a ver el resultado que aparece por consola:
Perfecto, la petición HTTP se ha realizado correctamente, al hacerlo obtenemos el data. Esta data se ha pasado al operador decode que ha transformado este valor en un objeto de nuestro dominio llamado DataModel. Y finalmente hemos obtenido este valor en el subscriber.
¿Qué ocurriría si hay un error al realizar la petición HTTP? Vamos a probarlo cambiando la url por una que no exista, vamos a usar la siguiente url
Si ahora compilamos, pulsamos COMMAND+SHIFT+ENTER, vemos por consola que al subscriber le llega un error.
Antes de acabar, mencionarte que hemos usado el operador tryMap para tener más granularidad y controlar qué ocurre en nuestro Publisher. Pero podríamos haber utilizado perfectamente el operador map:
Usando la API correcta, si volvemos a compilar, vemos que obtenemos el resultado correcto. El resultado es exactamente igual a lo que hemos visto en el ejemplo anterior.
Conclusión
Hoy hemos aprendido a cómo usar URLSession con Combine. Hemos usado un Publisher con varios operadores, tryMap, map y decode y luego nos hemos suscrito para recibir los valores de la petición HTTP y así transformar el JSON a un modelo de nuestro dominio.