¡Atención! Este sitio utiliza cookies.
Si no cambias la configuración de tu navegador, aceptas su uso.

Semillas de Cacao: iBeacons

En la anterior entrada vimos en qué consistían los beacons y qué usos podíamos darles. Esta vez veremos el código esencial para crearnos una app con la que trabajar con los iBeacons de Apple.

Sí majo sí, a eso vamos

Sí majo sí, a eso vamos

¿Qué necesitamos?

Buena pregunta.

Como nos vamos a dedicar a localizar balizas, pues nos harán falta balizas. Parece evidente pero no lo es, porque podremos utilizar nuestro iPhone como una en caso de que no las hayamos comprado. En todo caso necesitaremos:

  • Un pack de beacons y un dispositivo iOS.
  • Si no tenemos beacons, con 2 dispositivos iOS bastará: uno para usarlo como beacon y otro para localizarlo. Tu iPhone y tu iPad, por ejemplo. También nos sirven Macs con Mavericks y Bluetooth 4.0/BLE.
  • Y ni que decir tiene que el Xcode y algo de idea de Objective-C.

Eso sí, solo nos servirán dispositivos iguales o posteriores al

  • iPhone 4S.
  • iPad 3.
  • iPod de última generación.

Si tienes un iPhone 4 o un iPad 2 con iOS 7 no nos sirve.

Al tajo.

Creamos un proyecto nuevo en Xcode de tipo Single View Application.

Como mencioné en la anterior entrada, vamos a trabajar con CoreLocation, de modo que lo primero será añadir el framework al proyecto, importarlo a nuestro ViewController y añadir el protocolo <CLLocationManagerDelegate> a su cabecera.

Añadir Core Location

Ahora ya estamos listos para implementar y recibir las llamadas de nuestro esclavo delegado CoreLocation Manager, pero antes de ponernos a picar código vamos a echar un ojo a las clases que vamos a manejar.

  • Location Manager. Es nuestro delegado. Él nos chivará las regiones y los beacons que se vaya encontrando. Le crearemos una property y le asignamos nuestro controlador como delegado cuando sea necesario.
  • CLBeacon. Este será el objeto que representará cada uno de los beacons que recibamos.
  • CLBeaconRegion. Determina una región cerrada por iBeacons. Similar a la clase CLRegion, solo que no cuenta con centro geográfico ni un radio (_deprecated_ en iOS 7).

Y un par de conceptos básicos.

  • Beacon Region Identifier. Un string que identifique tus regiones, tipo com.batman.batbeacons.
  • iBeacon UUID. Un string para identificar tus iBeacons. Puedes generar el tuyo escribiendo en la Terminal de OS X uuidgen.

Creamos una región.

Definimos una región en CoreLocation mediante el método registerBeaconRegionWithUUID: andIdentifier:. Estos dos parámetros son los que he explicado en el paso anterior: el primero es el identificador de nuestra región y el segundo la UUID de nuestros beacons.

Es un nombre de método convencional que tendremos que implementar. Podéis llamarlo como os dé la gana realmente.

En él haremos lo siguiente: creamos el objeto CLBeaconRegion que iOS deberá monitorizar y reconocer gracias a los dos identificadores que hemos establecido.

Te habrás fijado en que no hemos creado ninguna instancia de locationManager en ninguna parte. Eso es porque lo he obviado, pero aquí tenéis una forma sencilla de hacerlo:

 

En este punto podemos establecer algunos parámetros para esta región.

  • La propiedad notifyEntryStateOnDisplay: pospondremos la notificación de que se ha encontrado una región cuando tengamos la pantalla encendida y estemos dentro de ella. Es útil, por ejemplo, por si queremos asegurarnos de que no hay interferencias, puesto que el iPhone estaría en la mano del usuario. El valor por defecto es NO.
  • El setter setNotifyOnEntry:. Admite valores YES/NO. Se nos notifica por defecto al entrar en la región. Su valor por defecto es YES.
  • El setter setNotifyOnExit. Lo mismo pero para notificar las salidas. Su valor por defecto también es YES.

Ahora que hemos registrado la región con la que trabajará nuestra app, ya podemos detectar cuándo nos encontramos dentro de ella con el método locationManager: didDetermineState: forRegion: de nuestro locationManager.

Aunque podéis utilizar también estos dos métodos:

Como veis, desde este método podemos preguntar si estamos dentro o fuera de la región. Si nos encontramos dentro, comenzamos a buscar beacons alrededor; si hemos salido, detenemos la búsqueda. Así de simple.

Un dato de implementación importante es que siempre hay que preguntar por la disponibilidad de rastreo antes de empezar a ‘olfatear’ nuestros beacons. Lo hacemos simplemente con [CLLocationManager isRangingAvailable].

¡A por los beacons!

Ahora que ya hemos localizado la región en la que ‘habitan’ nuestros beacons es hora de detectarlos.

Para eso simplemente implementamos el método locationManager: didRangeBeacons: inRegion: , que nos avisará cuando haya beacons en las cercanías y nos devolverá un array de todos ellos, en orden de cercanía (el primero será el que esté más cerca).

 

En este punto podemos recoger el que esté en la primera posición y hacer lo conveniente según su major y su minor (o bien podemos mostrar todos en una tabla).

Ya, pero es que yo no tengo balizas de esas…

En la fecha de creación de esta entrada yo tampoco. Pero como he comentado más arriba, no es un problema si tenemos 2 dispositivos iOS.

Para que podamos usar nuestro iPhone como beacon tendremos que importar el framework de CoreBluetooth y añadir las siguientes líneas donde corresponda (un UIViewController nuevo sería lo ideal porque si nos ponemos a emitir y detectar a la vez podría congelarse el Infierno, y no queremos que eso ocurra, que es a donde los del norte vamos de vacaciones) para activar la transmisión.

 

Hacerlo de esta forma tiene limitaciones, y es que si bloqueamos el teléfono o cambiamos de app se apaga la señal. Y por cierto, el código superior apenas realiza comprobaciones de ningún tipo, así que si por ejemplo no tienes el Bluetooth activado, no funcionará.

Qué pereza…

Mi MHJBostezosDelegate ha devuelto un array de ‘Zzzzz’.

patience_vader

Lasai, en un plis nos ponemos a buscar Alderaan Regions

No preocuparse, tenemos código bueno, bonito y barato. Bueno, al menos barato sí…

He subido a mi GitHub una app modelo (no, no es una 90-60-90) con una funcionalidad mínima (aquí mejor no cazar el doble sentido), para que podáis recrear este efecto en casa. Es un pequeño ‘juego’ de ‘Polis y Cacos’.

> FindMe app

Es un proyecto sencillo, con los métodos mínimos para funcionar y sin comprobaciones de ningún tipo para no perderse en detalles triviales. Encontraréis 3 clases dentro de la carpeta Controller:

  1. BeaconFinder. Es una clase de ejemplo. Está desarrollado todo lo mínimo y necesario para resumir lo explicado aquí.
  2. Cop. Es la clase que busca y muestra beacons cercanos. Es algo así como un radar de balizas.
  3. Robber. Es la clase que emite la señal bluetooth de baja frecuencia.

Suponiendo que una persona controla la app desde la clase Cop y el resto emite desde la clase Robber, se puede simular que buscamos balizas robadas. El policía iría detectando los beacons y recibiendo información sobre lo cerca que está de ellos.

Más…

Al igual que en la anterior entrada, os recomiendo echar un vistazo al trabajo de Pedro Muñoz, quien por cierto tiene un par de apps más completas que la mía y que además juegan con los minormajor. Aquí tenéis:

Podéis encontrar una entrada más completa aún que estas en el blog de Sendoa Portuondo, con teoría, mucho código muy bien explicado y alguna guinda muy bienvenida.

Y eso es todo. ¡Nos vemos en otro tutorial de ‘iOS para Dummies’™!

Podéis dejar sugerencias, quejas o insultos en los comentarios. Para vejaciones verbales de mayor nivel usad el formulario de contacto por favor. Si no funciona se pueden mandar pull requests sin matar a nadie. Muchas gracias.

Escrito por Miguel Hernández Jaso

Autor del blog. Desarrollador especializado en iOS.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Mi Gobierno me obliga a decirle que utilizo 'cookies' en mi página. Si continúa navegando, quiere decir que está conforme con ello.