06 Jul Tutorial de Introducción a Alamofire [Parte 2]
1. Introducción
Si has estado atento a las últimas publicaciones en EfectoApple, sabrás que en nuestro último Tutorial, estuvimos trabajando con Alamofire.
Hoy, vamos a continuar con la Segunda Parte de ese Tutorial sobre Alamofire.
En la Primera Parte del Tutorial, vimos toda la parte teórica que necesitábamos para poder comprender los conceptos básicos que nos permitieran desarrollar la aplicación que vamos a crear.
Estos son algunos de los apartados que revisamos en la Primera Parte del Tutorial:
- ¿Cuales son las mejores opciones para realizar peticiones a Servidor en iOS?
- ¿En qué consisten los verbos HTTP?
- Trabajando con JSON
- Funcionamiento de Alamofire
Como te digo, esta Primera Parte estaba centrada en explicar conceptos teóricos, que nos servirán para programar la aplicación que vamos a desarrollar hoy.
Puedes acceder a la Primera Parte del Tutorial desde aquí.
Veamos entonces, en qué nos centraremos en la Segunda Parte del Tutorial sobre Alamofire.
2. ¿Qué vamos a ver en este tutorial?
Desarrollaremos una aplicación completa que dispondrá de una UITableView en pantalla, donde mostraremos información recuperada de servidor, utilizando la librería Alamofire.
Se trata de un tutorial bastante completo, donde podrás ver en detalle como obtener datos a través de peticiones de red y como mostrar estos datos en pantalla.
Estos son todos los temas que vamos a ver en esta Segunda Parte del Tutorial:
- Como utilizar Apiary para mockear tus servicios
- Realizando peticiones con Alamofire
- Parseando la respuesta del servidor
- Mostrando datos en nuestra Aplicación iOS
Como puedes ver, una sencilla aplicación con una UITableView nos permitirá trabajar con conceptos fundamentales del Desarrollo iOS como peticiones a servidor, parseo de respuestas y muestra de datos recibidos.
3. La Aplicación que vamos a desarrollar
Este será el aspecto que tendrá la Aplicación al terminar:
Ya comenté en la Primera Parte del Tutorial, que se trata de una aplicación con una interfaz extremadamente sencilla, ya que lo único que muestra son 3 imágenes y 3 labels. Sin embargo, la parte invisible al usuario es más compleja y es perfecta para entender el funcionamiento de Alamofire.
A través de Alamofire, recuperaremos un conjunto de datos en formato JSON y los mostraremos en pantalla usando una UITableView.
He decidido usar un conjunto muy pequeño de datos, formado por 3 imágenes y 3 nombres. Podríamos crear un Tutorial con una mayor cantidad de datos, pero lo único que conseguiríamos sería complicar el desarrollo del mismo.
Con esta pequeña muestra de datos es más que suficiente para poder explicar el funcionamiento de Alamofire y que puedas utilizarlo en tus propios Proyectos iOS.
Estos son los pasos que seguiremos para desarrollar la App:
- Crearemos un prototipo de una API usando Apiary
- Este prototipo constará de un servicio web que nos devolverá el listado de Pokemons
- Usaremos Alamofire para recuperar los datos del servicio web
- Veremos como tratar esos datos recuperados
- Mostraremos los datos en nuestra Aplicación iOS
Se trata del clásico proceso de Desarrollo de una Aplicación iOS basada en una arquitectura cliente-servidor.
Es algo básico en cualquier Proyecto iOS y que espero que te ayude a comprender todos los pasos que hay que seguir.
4. Trabajando con Apiary
Empecemos explicando que es Apiary.
Apiary es un servicio que nos permite crear el prototipo de una API.
El diseño de APIs es algo complejo y en muchas ocasiones es difícil imaginar como va a usarse realmente una API que estamos desarrollando.
Apiary nos permite mockear (Trabajar con servicios de prueba) una API y crear prototipos, que podamos ir usando, mientras vamos creando la API.
Esto supone una gran ventaja, puesto que podemos ir testeando y corrigiendo el desarrollo.
Nosotros como Desarrolladores iOS no debemos de encargarnos del proceso de desarrollo de la API de nuestros productos, pero también podemos beneficiarnos de Apiary.
Vamos a ver como puedes crear el prototipo de una API de forma sencilla, formada por un servicio web, que devuelva un listado de datos.
Ese listado de datos estará formado por nuestra lista de Pokemons y será la base de nuestra aplicación iOS.
Veamos entonces los pasos que debemos seguir en Apiary.
Accediendo a Apiary
Lo primero que debes hacer es acceder a Apiary y crearte una cuenta de usuario.
Puedes acceder al servicio desde aquí.
Haz click donde pone Sign up now y crea una nueva cuenta de usuario.
Cuando la hayas creado, inicia sesión para poder utilizar el servicio.
Creando el Prototipo de nuestra API con Apiary
En la parte superior tendrás un menú similar a este:
Haz click en la opción Editor.
Desde esta opción, podrás crear el código que gestionará tu API.
Vamos a verlo con un ejemplo, para que sea más sencillo de entender.
Este es el código que yo he utilizado para crear la API de nuestra aplicación sobre Pokemons:
Las 2 primeras lineas vienen por defecto cada vez que creas una API. Puedes dejarlas tal y como están.
Después tenemos el título de nuestra API y una pequeña descripción de la misma:
Pokemon App is a simple API allowing consumers to view a short list of Pokemons
Lo interesante viene justo después.
He creado un servicio web al que se puede acceder a través de /pokemonList.
Justo después de esto, puedes ver la respuesta que obtendremos cuando realicemos una petición GET a este servicio web.
Cuando cualquier desarrollador acceda a nuestra API y realice una petición GET al servicio /pokemonList, obtendrá el JSON que hemos creado, con la lista de Pokemons:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[ { "id": "001", "name": "Bulbasaur", "image": "https://cdn0.iconfinder.com/data/icons/pokemon-go-vol-1/135/_bulbasaur-128.png" }, { "id": "004", "name": "Charmander", "image": "https://cdn0.iconfinder.com/data/icons/pokemon-go-vol-1/135/_charmander-128.png" }, { "id": "007", "name": "Squirtle", "image": "https://cdn0.iconfinder.com/data/icons/pokemon-go-vol-2/135/_squirtle-128.png" } ] |
Este es el corazón del prototipo de nuestra API y nos permitirá devolver datos a cualquier petición GET que realicen.
¿Cómo acceder a nuestra API en Apiary?
Tal vez tu pregunta, sea la siguiente:
¿Cual es la URL donde está alojada cualquier prototipo de API que desarrollemos en Apiary?
Para saber eso, deberás acceder al menú Inspector, situado en la parte superior de tu pantalla.
En este menú, podrás ver la URL del prototipo de tu API que utilizarás para realizar las peticiones.
Además, debajo de esta URL irá apareciendo información de todas las conexiones que reciba tu API.
Probando nuestra API
Vamos a copiar la URL de la API que aparece en el menú Editor. En mi caso, es esta:
1 |
http://private-5d2b9-efectoapplepokemonapp.apiary-mock.com |
La pegamos en el navegador.
Y obtendremos esto por pantalla:
Al acceder al endpoint de nuestra API, veremos en pantalla los servicios web y los métodos que la forman.
Como puedes ver, en mi caso, aparece el servicio web /pokemonList y el método GET que nos permitiría recuperar el listado de Pokemons.
Para acceder por tanto a ese servicio web, tendremos que añadirlo justo después de la URL de nuestra API.
Por tanto, al copiar en nuestro navegador, la siguiente URL:
1 |
http://private-5d2b9-efectoapplepokemonapp.apiary-mock.com/pokemonList |
Obtendremos por pantalla el listado de Pokemons que tenemos definido en Apiary:
Como puedes ver, de forma muy sencilla hemos construido el prototipo de una API totalmente funcional.
Puedes utilizar lo que acabas de aprender, para crear APIs que podrás usar para proveer de datos a tus Aplicaciones iOS.
Veamos ahora, como crear la App iOS que recuperará los datos de Apiary a través de Alamofire.
5. Nuestro Proyecto de Inicio
Como siempre, para intentar ahorrarte el máximo tiempo posible he creado un Proyecto de Inicio, a través del cual podrás comenzar a desarrollar la aplicación.
Descarga el Proyecto de Inicio desde aquí.
Una vez que lo has descargado, ábrelo.
Una vez abierto el proyecto en Xcode, echemos un vistazo rápido a la pinta que tiene.
Interfaz del Proyecto
Abre el fichero Main.storyboard y verás que dispone de una interfaz extremadamente sencilla:
Se trata de un Table View con una celda personalizada, que únicamente cuenta con un Label y una ImageView para representar el nombre y la imagen de cada Pokemon.
Celda Personalizada
Para poder gestionar los elementos que componen la celda que mostrará el nombre y la imagen de cada Pokemon, he creado la clase PokemonCell.swift que tiene el siguiente aspecto:
Como puedes ver, unicamente tenemos 2 Outlets que representan la imagen y el nombre de cada Pokemon y el constructor por defecto de la clase.
Nuestro ViewController
Por último, tenemos ViewController.swift, que será la clase donde trabajaremos para realizar el desarrollo de la app.
Accede a ella y verás exactamente esto:
No te preocupes si hay alguna cosa que no entiendes aquí, porque vamos a ir viendo, paso a paso todo el código que forma la clase ViewController.swift.
Tampoco tiene que importarte que nuestro proyecto produzca 2 errores de compilación. Se deben a que ahora mismo los métodos numberOfRowsInSection() y cellForRowAt() están vacíos.
Lo único que debes saber, es que esta es la clase donde iremos añadiendo el código que necesitamos para hacer que nuestra aplicación funcione.
¡Vamos a ello!
6. Desarrollando la Aplicación
Comencemos entonces a trabajar en la clase ViewController.swift.
Importando Alamofire en nuestro Proyecto
Lo primero que aparece en esta clase, son los import que necesitamos para poder utilizar la librería de Alamofire:
1 2 |
import Alamofire import AlamofireImage |
La primera linea nos permitirá utilizar Alamofire para recuperar datos de nuestra API en Apiary, mientras que la segunda linea nos facilitará el trabajo a la hora de trabajar con las imágenes de dicha API.
Estructuras que necesitaremos
Después tenemos la declaración de nuestra TableView y 3 estructuras que necesitaremos para trabajar con los datos de la aplicación:
1 2 3 4 5 |
@IBOutlet weak var tableView: UITableView! var jsonArray: NSArray? var nameArray: Array<String> = [] var imageURLArray: Array<String> = [] |
- jsonArray nos permitirá almacenar el array que contiene todos los datos de nuestra API
- nameArray servirá para guardar los nombres de los Pokemons
- imageURLArray será la estructura en la que almacenaremos las URLs de las imágenes de los Pokemons, que aparecen en la API
El método downloadDataFromAPI()
Si te fijas, en el método viewDidLoad(), además de hacer la asignación del Delegado y el DataSource de nuestra Tabla, realizamos una llamada a la función downloadDataFromAPI().
Esta es la función que gestionará la recuperación de datos de Apiary. Ahora mismo está vacía, pero veamos paso a paso como añadir el código que necesitamos.
Te voy a presentar el código que deberás añadir a la función downloadDataFromAPI() y justo después explicaremos cada una de las lineas:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
func downloadDataFromAPI(){ //1. Alamofire.request("http://private-5d2b9-efectoapplepokemonapp.apiary-mock.com/pokemonList") .responseJSON { response in //2. if let JSON = response.result.value{ //3. self.jsonArray = JSON as? NSArray //4. for item in self.jsonArray! as! [NSDictionary]{ //5. let name = item["name"] as? String let imageURL = item["image"] as? String self.nameArray.append((name)!) self.imageURLArray.append((imageURL)!) } //6. self.tableView.reloadData() } } } |
//1. Realizamos la llamada a nuestra API, a través de la función request() de Alamofire, utilizando la URL de Apiary
//2. Almacenamos la respuesta del servidor (response.result.value) en la constante JSON
//3. Utilizamos la estructura jsonArray para almacenar la respuesta del servidor, especificando que se trata de un Array. Sabemos esto, porque conocemos la estructura que tiene nuestro json en Apiary
//4. Recorremos jsonArray y vamos recuperando cada uno de los diccionarios (Que corresponden a cada uno de los Pokemons).
//5. Cada vez que recuperamos uno de los diccionarios, que representa a un Pokemon, recuperamos su nombre, a través de la clave “name” y su imagen a través de la clave “image” y los almacenamos en los arrays nameArray e imageURLArray respectivamente.
//6. Por último, es necesario que recarguemos la TableView, usando la función reloadData(), para que nuestra TableView pueda mostrar los datos que acabamos de recuperar del servidor.
Con esta función, acabamos de recuperar los datos del servidor y los hemos almacenado en las estructuras de nuestra aplicación. Sería mejor utilizar 2 funciones diferentes, una para cada tarea, aunque por no alargar el Tutorial he elegido esta forma de hacerlo.
Ahora que ya hemos recuperado los datos de Apiary, nos faltaría mostrarlos en la TableView.
Veamos como hacerlo.
Funciones de nuestro TableView()
Las 2 funciones con las que trabajaremos para mostrar los datos en el TableView son:
- numberOfRowsInSection()
- cellForRowAt()
Aquí tienes el código que deberás añadir a cada una de ellas y justo después la explicación paso a paso:
1 2 3 |
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return self.nameArray.count } |
La función numberOfRowsInSection() únicamente debe especificar el número de celdas que tendrá nuestra tabla. Usaremos la función count() para devolver el número de elementos que contiene nuestro array nameArray. Este array contiene 3 elementos, que son los 3 Pokemons que hemos recuperado desde Apiary.
1 2 3 4 5 6 7 8 9 10 11 |
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! PokemonCell cell.pokemonName.text = self.nameArray[indexPath.row] let url = URL(string: self.imageURLArray[indexPath.row]) cell.pokemonImage.af_setImage(withURL: url!) return cell } |
En la función cellForRowAt() lo primero que haremos será crear una celda de tipo PokemonCell.
Después, le asignaremos al nombre de esta celda cada uno de los nombres de los Pokemons que tenemos almacenados en nameArray.
Para poder establecer la imagen de cada Pokemon, crearemos una constante de tipo URL a partir de cada una de las URLs almacenadas en imageURLArray y la usaremos para recuperar la imagen, utilizando la función af_setImage() de AlamofireImage.
Para finalizar devolveremos nuestra celda.
Con este método, has terminado la implementación de tu Aplicación.
Si ejecutas el proyecto, podrás ver como se muestra en el Simulador nuestro listado de 3 Pokemons, con sus nombres e imágenes.
Nuestra Aplicación ha quedado perfecta.
7. Un Reto para ti
Al ejecutar la aplicación y dependiendo de la conexión de la que dispongas, es posible que la aplicación tarde un poco en recuperar los datos de Apiary.
Siempre que el usuario deba esperar por algo en nuestra aplicación debemos de informarle en pantalla con algún indicador de carga.
Como nuestra aplicación ahora mismo no tiene ningún indicador de carga, está incompleta.
Por tanto, mi reto para ti es el siguiente:
Añadir un Indicador de Carga a esta aplicación que informe al usuario que se están solicitando datos al servidor. Evidentemente cuando la aplicación haya recibido estos datos, el indicador de carga deberá desaparecer de la pantalla.
Si tienes dudas sobre como poder hacerlo, aquí tienes otro Tutorial, en el que implementé esta funcionalidad en otra Aplicación. Concretamente deberás revisar el Apartado 8 del Tutorial:
Añadiendo Indicador de Carga a nuestra App
Si eres capaz de conseguir este Reto, te propongo que me envíes por email tu Proyecto terminado a:
luis@efectoapple.com
Le echaré un vistazo y comprobaré si está correctamente desarrollado.
8. Resumen final
Este Tutorial sobre Alamofire, formado por 2 partes diferentes es uno de los más extensos que he desarrollado en EfectoApple.
Espero que te haya servido para comprender como puedes utilizar esta librería en tus Proyectos iOS.
Aquí tienes un pequeño resumen de los puntos más importantes que hemos visto:
- ¿Qué opciones tenemos para realizar peticiones a servidor en Desarrollo iOS?
- ¿Cuales son y en que consisten los verbos HTTP?
- Breve introducción a JSON
- Como realizar peticiones simples con Alamofire
- Serializando las respuestas con Alamofire
- Configurando el verbo de la petición
- Configurar las cabeceras de la petición
- Como realizar peticiones con parámetros con Alamofire
- Como podemos enviar JSON en el body de la petición
- Como utilizar Apiary para mockear tus servicios
- Realizando peticiones con Alamofire
- Parseando la respuesta del servidor
- Mostrando datos en nuestra Aplicación iOS
9. Descarga el Proyecto terminado
Tal vez quieras echar un vistazo al código fuente de la Aplicación terminada.
Puedes descargar el Proyecto finalizado directamente desde aquí.
10. Has terminado el Tutorial
Has acabado el tutorial de esta semana en EfectoApple. Como siempre, aquí tienes tu recompensa en forma de video:
11. ¿Donde ir ahora?
Si no quieres perderte ningún tutorial de EfectoApple, puedes suscribirte a nuestra Newsletter, a través del formulario que tienes al final de este post.
Puedes acceder a más tutoriales disponibles en EfectoApple, desde aquí.
Si este artículo te ha parecido útil, me harías un gran favor compartiéndolo en tus redes sociales.
Y como siempre, para cualquier duda, tienes los comentarios a tu disposición.
tery
Publicado a las 07:09h, 09 agostobuenas noches soy nueva en esto al compilar la aplicación me marca un error en import Alamofire me marca que no es un mòdulo del proyecto, gracias por toda la informaciòn que nos brindan es de mucha ayuda =D
Luis R
Publicado a las 13:33h, 28 agostoHola Tery.
Pásame la descripción exacta del error.
Saludos.
Roberto Hevens Gonzalez
Publicado a las 18:59h, 12 octubreEstimado Luis
He bajado la App completa desde el tutorial “Alamofire” parte 2 “pokemonApp”. sin tocar nada el proyecto me da un error en el archivo ViewController.swift en la linea ‘Import Alamofire’ cannot load underlying module for ‘Alamofire’.
Este error no me permite hacer nada. He bajado también “TestingCocoapods” y no me da ningún error. Instale sin errores el CocoaPods.
Ordenador MacBookPro 2017 – macOS High Sierra -Xcode 9 – Swift 4
Cuando puedas me necesitaría una solución.
Saludos
Roberto
Luis R
Publicado a las 10:06h, 25 octubreHola Roberto.
Es extraño lo que me comentas. Acabo de bajar el proyecto y lo he ejecutado sin problema.
He encontrado tu mismo problema, aunque de una versión anterior, aquí:
https://stackoverflow.com/questions/31674885/cannot-load-underlying-module-for-alamofire
Estas son las posibles soluciones que comentan:
– Verificar la versión de tu xcodebuild
– Hacer un Clean All
– Hacer limpieza de la carpeta DerivedData y la Caché de Xcode.
Échale un ojo y sigue los pasos indicados a ver si conseguimos solucionarlo.
Un saludo.
Roberto Hevens Gonzalez
Publicado a las 11:51h, 09 noviembreMuchas gracias
Roberto
Luis R
Publicado a las 14:50h, 12 noviembreUn placer Roberto.
Carlos Rocha
Publicado a las 02:22h, 21 septiembreLo mas probable es que no estan abriendo el xcworkspace si no abren ese archivo les dara el error,
No se abre el xcodeproj porque se uso cocoapod para instalar la app alamofire
saludos
Eric
Publicado a las 10:34h, 17 eneroExcelente tutorial.
¡Cada día más pulido!
Pd: puedes hacer un tutorial referente a cómo mantener el login de las aplicaciones, es decir cuando cierres el proceso no pierdas el login.
Saludos
Francisco Jose Villa
Publicado a las 15:58h, 21 febreroMuy buenas!! Estoy trabajando con Api REST y quiero hacer un login con los usuarios registrados en mi blog. ¿Es muy complicado? Muchas gracias