08 Ago Crea tu Aplicación iOS Cliente-Servidor [Parte 1]
1. Introducción
Lo primero de todo, si has trabajado antes en alguna aplicación iOS cliente-servidor, lo más probable es que hayas trabajado con JSON. Si este es tu caso, puedes pasar directamente al punto 2 de este tutorial.
Si por el contrario no tienes experiencia anterior con JSON, aquí tienes una brevísima introducción que te permitirá seguir paso a paso este tutorial.
¿Qué es JSON?
JSON es el acrónimo de JavaScript Object Notation. Es un formato de texto ligero para el intercambio de datos. Es comúnmente usado para representar datos estructurales y para intercambiar datos en aplicaciones cliente-servidor. Es una alternativa moderna al clásico XML. Una gran cantidad de los servicios que utilizamos todos los días tienen APIs basadas en JSON. La mayor parte de las aplicaciones de iOS como Twitter o Facebook envían datos a los servicios web de sus backends en formato JSON.
Como ejemplo, aquí tenemos una representación de un objeto Película en formato JSON:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
{ "title": "X-Men: Apocalipsis", "release_date": "20/05/2016", "director": "Bryan Singer", "cast": [ { "name": "James McAvoy", "character": "Professor Charles Xavier" }, { "name": "Michael Fassbender", "character": "Erik Lehnsherr / Magneto" }, { "name": "Jennifer Lawrence", "character": "Raven / Mystique" } ] } |
En este JSON de ejemplo, podemos observar un objeto Película con los siguientes campos:
- Título
- Fecha de lanzamiento
- Director
- Reparto (Un array de diccionarios, donde cada diccionario representa a un actor y su personaje)
Como puedes ver, los datos en formato JSON son más fáciles de leer y parsear que en XML.
Si nunca antes habías oído hablar de JSON y quieres aprender más sobre él, puedes echar un vistazo a esta Guía de JSON: Guía de JSON
Desde hace varios años, el SDK de iOS es capaz de trabajar de forma nativa con JSON. En este tutorial veremos como recuperar y parsear datos en formato JSON de la API de Meetup utilizando la clase NSJSONSerialization.
2. ¿Qué vas a aprender en este tutorial?
En este tutorial veremos los siguientes puntos:
- Diseñar la arquitectura de una aplicación iOS cliente-servidor.
- Como crear el modelo de datos de nuestra aplicación.
- Seguir los pasos necesarios para registrarte en la API de Meetup.
- Realizar peticiones a esta API para poder obtener los datos que necesitamos en formato JSON.
- Interpretar y parsear esos datos utilizando NSJSONSerialization.
- Como trabajar con el patrón de diseño Facade.
[caja-gris]Si crees que alguno de estos puntos puede ser interesante para ti, sigue adelante, ¡COMENZAMOS![/caja-gris]
3. Echando un vistazo a nuestra app
En este tutorial vamos a crear una app muy simple llamada BrowseMeetup que consumirá la API pública de Meetup. Si nunca has oído hablar de Meetup, debes saber que es la red más grande del mundo para organizar reuniones de grupos con intereses comunes. A través de ella puedes crear grupos locales o encontrar alguno entre los miles disponibles. Al igual que otras redes sociales ofrece una API pública para acceder a sus datos desde tus propias aplicaciones.
Nuestra app BrowseMeetup consumirá el servicio web de Meetup para buscar grupos en Madrid. La app conectará con la API de Meetup, recuperará los datos y los mostrará por pantalla.
A nivel de interfaz, nuestra aplicación será muy sencilla. Dispondremos de un Navigation Controller y un TableViewController. Simplemente mostrará una TableView, donde se detallará cada uno de los grupos de Meetup disponibles en Madrid.
En este caso lo verdaderamente importante del tutorial sucede de forma invisible al usuario.
Para que te hagas una idea de lo que queremos conseguir, este será el aspecto de nuestra aplicación, una vez que esté terminada:
[caja-gris]Un lector de EfectoApple ha desarrollado este proyecto en Swift. Puedes acceder a este código directamente desde el apartado 9 de la segunda parte del tutorial[/caja-gris]
4. Comenzando
El objetivo de este tutorial es aprender a trabajar con datos en formato JSON utilizando NSJSONSeralization, por lo que vamos a ahorrarnos todo el proceso de configuración del proyecto y creación de la interfaz y a trabajar directamente con este proyecto creado por mi: Descarga el proyecto inicial.
[caja-gris]El proyecto se ha creado para un tamaño de 4,7 pulgadas, por lo que para un funcionamiento óptimo debes ejecutarlo en el simulador para iPhone 6 de Xcode[/caja-gris]
Es simplemente un proyecto creado por mi desde cero, donde ya está creada la interfaz de la aplicación, para poder ahorrarnos tiempo y centrarnos en lo importante: La conexión con la API de Meetup y el tratamiento de los datos que nos devuelve.
Descarga el proyecto, ábrelo en Xcode y vamos a echarle un vistazo.
Como puedes ver, se llama MeetupProject. Abre el fichero Main.storyboard para poder ver la interfaz de la aplicación.
Como puedes observar se trata de una interfaz muy simple, donde tendremos una TableView con varias celdas y en cada celda utilizaremos 4 labels para mostrar la información:
- Label para el nombre del grupo de Meetup (z)
- Label para el nombre de los organizadores del grupo (Who)
- Label para la descripción del grupo (Lorem Ipsum…)
- Label para la localización del grupo (City, Country)
Aparte de la interfaz no hay nada más implementado en este proyecto, por lo que es perfecto para comenzar con nuestro tutorial. Así que sin perder más tiempo…
!Comenzamos!
5. Trabajando con la API de Meetup
Antes de poder utilizar la API de Meetup, primero deberás crear una nueva cuenta en Meetup. Para comenzar, entra en APIs Doc y haz click en el botón “Request to join Meetup group”, después elige la forma de registro, ya sea mediante Facebook, Google o por email.
Rellena la información que te vayan solicitando hasta que veas este mensaje en pantalla:
Eso querrá decir que ya puedes utilizar la API de Meetup en tus aplicaciones.
Dentro de la API de Meetup y en cualquier API en general existen una serie de métodos a los que debemos de llamar para obtener la información que queramos. Cada método devuelve un tipo de información diferente.
En nuestro caso vamos a utilizar el método GET /2/groups
Tal y como se explica en el enlace, éste método permite obtener información sobre los grupos de Meetup. Si echas un vistazo a los parámetros que acepta verás que permite especificar la latitud y longitud de una ubicación determinada para devolver los grupos cercanos a esa localización. Eso será lo que hagamos. Especificaremos la latitud y longitud de un punto concreto y obtendremos los grupos de Meetup que estén ubicados cerca de él.
Meetup además nos ofrece una Consola API donde podemos realizar peticiones de prueba y ver las respuestas que obtenemos. Es perfecto para practicar y entender el funcionamiento de la API.
Te animo a que pruebes la herramienta y veas como modificando los parámetros de entrada varían las respuestas recibidas del servidor.
Como ejemplo, aquí tienes una petición realizada por mí, donde especifico los siguientes parámetros:
- latitud = 40,396916
- longitud = -3,608977
- page = 1 (Éste parámetro se refiere al nº máximo de grupos que quieres recibir en la respuesta)
1 |
https://api.meetup.com/2/groups?&sign=true&photo-host=public&lat=40.396916&lon=-3.608977&page=1 |
Y aquí tienes parte de la respuesta que produce (He omitido algunas partes para que sea más legible):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
{ "results":[ { "utc_offset":7200000, "country":"ES", "visibility":"public", "city":"Madrid", "timezone":"Europe/Madrid", "created":1034097748000, "topics":[ { "urlkey":"spanish", "name":"Idioma español", "id":183 }, { "urlkey":"french", "name":"Idioma francés", "id":185 }, { "urlkey":"newintown", "name":"Nuevo en la ciudad", "id":1273 }, { "urlkey":"nightlife", "name":"Vida nocturna", "id":4392 }, { "urlkey":"socialnetwork", "name":"Hacer contactos", "id":4422 }, { "urlkey":"language", "name":"Idioma y cultura", "id":10454 }, { "urlkey":"social", "name":"Vida social", "id":10581 }, { "urlkey":"fun-times", "name":"Diversión", "id":15117 }, { "urlkey":"dancing", "name":"Baile", "id":17571 }, { "urlkey":"eating-drinking-talking-laughing-etc", "name":"Comer, beber, hablar, reír, etc.", "id":19130 }, { "urlkey":"spanish-culture", "name":"Cultura española", "id":19169 }, { { "urlkey":"english-language", "name":"Inglés", "id":25698 }, { "urlkey":"language-exchange", "name":"Intercambio lingüístico", "id":26212 }, { "urlkey":"international-friends", "name":"Amigos internacionales", "id":50881 }, { "urlkey":"culture-exchange", "name":"Intercambio cultural", "id":67622 } ], "link":"http://www.meetup.com/Language-Exchange-Madrid/", "rating":4.67, "description":"WELCOME, BIENVENIDOS to the oldest, most international, crowded and active Meetup group in Madrid!", "lon":-3.7100000381469727, "group_photo":{ "highres_link":"http://photos1.meetupstatic.com/photos/event/1/f/7/4/highres_202088052.jpeg", "photo_id":202088052, "photo_link":"http://photos1.meetupstatic.com/photos/event/1/f/7/4/600_202088052.jpeg", "thumb_link":"http://photos1.meetupstatic.com/photos/event/1/f/7/4/thumb_202088052.jpeg" }, "join_mode":"open", "organizer":{ "member_id":240168, "name":"David", "photo":{ "highres_link":"http://photos4.meetupstatic.com/photos/member/a/c/7/a/highres_644154.jpeg", "photo_id":644154, "photo_link":"http://photos2.meetupstatic.com/photos/member/a/c/7/a/member_644154.jpeg", "thumb_link":"http://photos4.meetupstatic.com/photos/member/a/c/7/a/thumb_644154.jpeg" } }, "members":7104, "name":"Spanish & International Friends in Madrid LANGUAGE EXCHANGES", "id":146102, "urlname":"Language-Exchange-Madrid", "category":{ "name":"language/ethnic identity", "id":16, "shortname":"language" }, "lat":40.41999816894531, "who":"International talkers" } ], "meta":{ "next":"https://api.meetup.com/2/groups?offset=1&sign=True&format=json&lon=-3.608977&photo-host=public&page=1&radius=25.0&fields=&lat=40.396916&order=id&desc=false", "method":"Groups", "total_count":1215, "link":"https://api.meetup.com/2/groups", "count":1, "description":"None", "lon":-3.608977, "title":"Meetup Groups v2", "url":"https://api.meetup.com/2/groups?offset=0&sign=True&format=json&lon=-3.608977&photo-host=public&page=1&radius=25.0&fields=&lat=40.396916&order=id&desc=false", "signed_url":"https://api.meetup.com/2/groups?offset=0&format=json&lon=-3.608977&photo-host=public&page=1&radius=25.0&fields=&lat=40.396916&order=id&desc=false&sig_id=183979886&sig=5ee3c7065843371486762c65fcd419913edb4c26", "id":"", "updated":1465226367000, "lat":40.396916 } } } |
No te preocupes si no eres capaz de entenderlo completamente. De este JSON, lo único con lo que tienes que quedarse es que está dividido en dos partes: results y meta. Nosotros únicamente necesitaremos la parte de results, ya que es donde aparece la información que queremos mostrar en nuestra app.
6. Diseño de la aplicación y como funciona
Antes de comenzar a desarrollar, vamos a explicar el diseño de clases nuestra aplicación iOS Cliente-Servidor. Ya hemos mencionado antes que la API de Meetup ofrece este método para obtener los grupos situados cerca de una localización determinada.
Este método nos devolverá esa información en formato JSON.
Nuestra aplicación deberá recuperar esta información y construir los objetos que utilizaremos en nuestra app.
Justo debajo tienes un esquema del diseño de nuestra aplicación, mostrando como están estructuradas las clases y como trabajan juntas para obtener los grupos de Meetup:
Si a primera vista hay partes que no entiendes, no te preocupes, lo vamos a ver en detalle:
- La clase MeetupManager será la encargada de solicitar los grupos de Meetup para una localización concreta. Aquí la clase MeetupManager actúa como un coordinador de otras clases. Es lo que se conoce como el Patrón de Diseño Facade (Fachada en castellano). Si nunca antes has oído hablar de él no te preocupes, quédate con que se trata de una clase coordinadora de otras clases. El patrón Facade intenta ofrecer una interfaz simplificada al view controller y protegerlo de toda la implementación subyacente.
- La clase MeetupCommunicator es utilizada para comunicarse con la API de Meetup. Una vez que Meetup ha respondido con datos en formato JSON, pasaremos este JSON a la clase GroupBuilder que será la encargada de construir el objeto Grupo.
- La clase MasterViewController se encarga de presentar los grupos en su TableView obtenidos a través de la clase MeetupManager.
7. Creando el Modelo de Datos para gestionar el JSON
Ahora si, vamos a comenzar a crear nuestra aplicación. Para ello comenzaremos creando nuestro modelo de datos. Sabiendo que el método de la API de Meetup que vamos a utilizar devuelve un conjunto de grupos, lo lógico sería que creáramos una clase Grupo para almacenar esa información.
Aquí tienes un ejemplo de respuesta JSON de un objeto Grupo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
{ "utc_offset":7200000, "country":"ES", "visibility":"public", "city":"Madrid", "timezone":"Europe/Madrid", "created":1034097748000, "topics":[ { "urlkey":"spanish", "name":"Idioma español", "id":183 }, { "urlkey":"french", "name":"Idioma francés", "id":185 }, { "urlkey":"newintown", "name":"Nuevo en la ciudad", "id":1273 }, { "urlkey":"nightlife", "name":"Vida nocturna", "id":4392 }, { "urlkey":"socialnetwork", "name":"Hacer contactos", "id":4422 }, { "urlkey":"language", "name":"Idioma y cultura", "id":10454 }, { "urlkey":"social", "name":"Vida social", "id":10581 }, { "urlkey":"fun-times", "name":"Diversión", "id":15117 }, { "urlkey":"dancing", "name":"Baile", "id":17571 }, { "urlkey":"eating-drinking-talking-laughing-etc", "name":"Comer, beber, hablar, reír, etc.", "id":19130 }, { "urlkey":"spanish-culture", "name":"Cultura española", "id":19169 }, { "urlkey":"english-language", "name":"Inglés", "id":25698 }, { "urlkey":"language-exchange", "name":"Intercambio lingüístico", "id":26212 }, { "urlkey":"international-friends", "name":"Amigos internacionales", "id":50881 }, { "urlkey":"culture-exchange", "name":"Intercambio cultural", "id":67622 } ], "link":"http://www.meetup.com/Language-Exchange-Madrid/", "rating":4.67, "description":"WELCOME, BIENVENIDOS to the oldest, most international, crowded and active Meetup group in Madrid!", "lon":-3.7100000381469727, "group_photo":{ "highres_link":"http://photos1.meetupstatic.com/photos/event/1/f/7/4/highres_202088052.jpeg", "photo_id":202088052, "photo_link":"http://photos1.meetupstatic.com/photos/event/1/f/7/4/600_202088052.jpeg", "thumb_link":"http://photos1.meetupstatic.com/photos/event/1/f/7/4/thumb_202088052.jpeg" }, "join_mode":"open", "organizer":{ "member_id":240168, "name":"David", "photo":{ "highres_link":"http://photos4.meetupstatic.com/photos/member/a/c/7/a/highres_644154.jpeg", "photo_id":644154, "photo_link":"http://photos2.meetupstatic.com/photos/member/a/c/7/a/member_644154.jpeg", "thumb_link":"http://photos4.meetupstatic.com/photos/member/a/c/7/a/thumb_644154.jpeg" } }, "members":7104, "name":"Spanish & International Friends in Madrid LANGUAGE EXCHANGES", "id":146102, "urlname":"Language-Exchange-Madrid", "category":{ "name":"language/ethnic identity", "id":16, "shortname":"language" }, "lat":40.41999816894531, "who":"International talkers" } |
Este JSON representa un Grupo en Meetup. No vamos a usar todos los datos que recibimos en este JSON. Simplemente utilizaremos los campos:
- Name
- Description
- Who
- Country
- City
Estos campos son suficientes para presentar la información que necesitamos en la TableView de nuestra app.
Una vez que ya sabemos cuales son los campos que necesitamos, ya podemos crear nuestra clase modelo: Group.
Para ello haz en Xcode: File > New File…, elige Cocoa Class, dale el nombre Group, y haz que herede de la clase NSObject.
Una vez que hayas creado nuestra clase modelo, añade el siguiente código en su fichero header (Group.h):
1 2 3 4 5 6 7 8 9 |
@interface Group : NSObject @property (copy, nonatomic) NSString *name; @property (copy, nonatomic) NSString *description; @property (copy, nonatomic) NSString *who; @property (copy, nonatomic) NSString *country; @property (copy, nonatomic) NSString *city; @end |
Estas propiedades serán las que almacenen la información que mostraremos en nuestra app.
Si te das cuenta, al declarar estas propiedades, Xcode mostrará un warning debido a la property description. Esto se debe a que nuestra clase Group hereda de NSObject. NSObject es la clase raíz de la que heredan todas las clases en iOS. Este warning se produce porque la clase NSObject ya tiene una propiedad llamada description (Puedes comprobarlo accediendo a la clase NSObject desde Xcode y haciendo una búsqueda “description”. Por este motivo, Xcode, nos muestra este warning. Para solucionarlo, lo único que tendremos que hacer será sintetizar nuestra propiedad. Es decir, vamos a Group.m y añadimos esta linea:
1 |
@synthesize description; |
Volvemos a compilar (Cmd+B) y veremos que el warning ha desaparecido.
8. Resumen de nuestra aplicación iOS cliente-servidor
Hasta ahora, hemos visto como diseñar la arquitectura de clases de nuestra aplicación, como crear el modelo de nuestra app, basándonos en la respuesta JSON y también hemos seguidos los pasos necesarios para registrarnos en la API de Meetup, lo que nos permitirá obtener los datos que mostraremos por pantalla. Sigue avanzando y pronto tendrás una aplicación cliente-servidor totalmente funcional.
9. ¿Donde ir ahora?
Hasta aquí la primera parte del tutorial Crea tu Aplicación iOS Cliente-Servidor.
Si quieres acabar la aplicación que has comenzado, por favor, continúa a la segunda parte del tutorial.
Sin comentarios