La Rebelión de los iBeacons por @pmunoz08

| Última modificación: 10 de noviembre de 2022 | Tiempo de Lectura: 7 minutos

Algunos de nuestros reconocimientos:

Premios KeepCoding

En el pasado WWDC 2013, se presentaron los ibeacons como una característica más de las novedades en iOS7,  casi nadie le dio la importancia que se merecían (es mi opinión personal), pero poco a poco han ido ganando popularidad según se les ha ido descubriendo el potencial que tienen y la cantidad de oportunidades que ofrecen. En este artículo vamos a tratar de ver qué son y cómo funcionan.

¿Qué es un iBeacon?

Su inicio data del 2007, cuando Nokia creó Wibree, punto de inicio de BLE. Funciona bajo el protocolo BLE (Bluetooth 4.0) junio 2010 y tiene la capacidad de estar continuamente enviando información y poder leerla desde otro dispositivo sin tener la necesidad de enlazarlo.

CB 4.0 emite en una frecuencia de 2.4GHz, divididos en 39 canales de 2.0 MHz. (36 primeros para intercambio de datos con dispositivos enlazados, los otros 3 son los usados para “Advertising”)

Tiene un alcance 50-70m dependiendo de posibles interferencias.

En el WWDC  los definieron como : “a new class of low-powered, low-cost transmitters that can notify nearby iOS 7 devices of their presence.”

Soportado por :

  • iPhone 4S y posteriores
  • iPad3 y posteriores
  • iPod touch 5ª generación
  • Macs con Mavericks y Bluetooth 4.0
El iBeacon en la pared detecta el móvil y envía la información_iBeacons
El iBeacon en la pared es detectado por el móvil.

Aunque Bluetooth 4.0 está soportado desde iOS 5.0 hasta iOS 7 no hemos contado una api para trabajar con beacons incluyendo en el  Framework Core Location:

  • Nuevos métodos en el protocolo CLLocationManagerDelegate
  • CLBeacon
  • CLBeaconRegion

Dentro de Bluetooth LE hay dos grupos o conceptos:

  • Peripheral. Informan de servicios y expone sus características (properties).
  • Central. Buscar servicios y leen/escriben las propiedades del mismo.

Un iBeacon es un “Peripheral” que expone sus características pero no es un servicio BLE. Algunos beacons  trabajan como servicio para permitir su configuración.

Interactuar con un iBeacon: CLLocationManagerDelegate

Como comentábamos antes, para poder interactuar con iBeacons en iOS7 se han añadido algunos métodos al protocolo CLLocationMAnagerDelegate:

locationManager:didDetermineState:forRegion:  El CLLocationManager llama a este método cuando se pasa la frontera de una region. CLREgionState: (CLRegionStateUnknown, CLRegionStateInside, CLRegionStateOutside)

locationManager:didRangeBeacons:inRegion:  El CLLocationMAnager llama a este método cuando detecta beacons o dejar de detectarlos. Los iBeacosn detectados se reciben en un aray ordenados por proximidad. El más cercano el primero.

locationManager:rangingBeaconsDidFailForRegion:withError: Si una CLBeaconRegion contiene datos no válidos o falla al registrase.

requestStateForRegion: Nos permite preguntar por estado del dispositivo en relación con una región.

CLBeacon

Hereda de NSObject y representa a los iBeacons encontrados en una CLBeaconRegion. Nos provee de las siguientes propiedades:

proximityUUID. Un ID global, por ejemplo para identificar una compañía.

major y minor. Permite crear áreas o secciones de beacons

proximity. Distancia relativa a un iBeacon (Inmediate, Near, Far, Unknown)

accuracy. Distancia en metros. No posición exacta, determinada en función de rssi.

rssi. Fuerza de la señal recibida medida en Db

CLBeaconRegion

Hereda de CLRegion, define una región basada en la proximidad de un dispositivo a un CLBeacon. Nos ofrece 3 inicializadores:

initWithProximityUUID:identifier:

initWithProximityUUID:major:identifier:

initWithProximityUUID:major:minor:identifier:

En función de ellos podemos crear regiones que contengan 1 o varios beacons, si no identificamos el minor, puede haber más de 1 beacon con el mismo proximitYUDID y major. Un ejemplo para crear una región formada por 1 beacon sería:

CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
                                                                     major:major
                                                                     minor:minor
                                                                identifier:kBeaconIdentifier];

El “identifier” es una cadena de texto que nos permitirá identificar la región en la que está el dispositvo si lo necesitamos, por ejemplo cuando hay varias regiones

Otro método importante incluido en iOS7:

peripheralDataWithMeasuredPower: Devuelve un diccionario con la información que identifica al beacon codificada además de la información a trnasmitir. Este diccionario se debe pasar a una instancia de CBPeropheralMAnager al método startAdvertising. Este es uno de los pasos a realizar para convertir nuestro dispositivo en un iBeacon. Lo veremos despues en un ejemplo.

El parámetro measuredPower es opcional, representa la medida de la fuerza de la señal a 1 metro de distancia del beacon.

Propiedades:

notifyEntryStayOnDisplay.  Si su valor es YES, el sistema avisará a nuestra app mediante el  método del protocolo de ClLocationMAnager locationManager:didDetermineState:forRegion: cuando el usuario enciende la pantalla del dispositivo y está dentro de la región, incluso si la app no está corriendo, en este caso la app se lanza en background. Ojo que la app no esté corriendo se refiere a que esté inactiva porque la ha parado el SO, si la apara el usuario, la app no recibirá notificaciones.  Su valor por defecto es NO.

Además con en IOS7, podemos indicar si queremos que se nos informe al salir o entrar de una región, es es nuevo en CLRegion, no es específico de CLBeaconRegion:

notifyOnEntry.  llamará a locationManager:didEnterRegion: cuando se entre en una región .Default Yes

notifyOnExit.  llamará a locationManager:didExitRegion: cuando se salga en una región .Default Yes

Monitoring CLBeaconRegions

No tiene mucha ciencia, es como monitorizar regiones  como se hacía hasta ahora, solo que las regiones serán CLBBeaconRegions, la diferencia es que cuando detectamos que estamos dentro de una región, es cunado empezaremos a intentar los beacons cercanos a nosotros “Ranging beacons”. Vemos un ejemplo:

self.locManager = [[CLLocationManager alloc] init];
[self.locManager setDelegate:self];

if ([CLLocationManager isRangingAvailable]) {

   NSUUID *proximityUUID = [[NSUUID alloc] initWithUUIDString:UUIDiBeacon];

   self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:proximityUUID identifier:@"com.softpmc.beacons"];

   [self.beaconRegion setNotifyEntryStateOnDisplay:YES];
   [self.locManager startMonitoringForRegion:self.beaconRegion];
 }

#pragma mark - CLLocationManagerDelegate

    - (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region{
        if (state == CLRegionStateInside) {

            [self.locManager startRangingBeaconsInRegion:(CLBeaconRegion *)region];
        } else {

            [self.locManager stopRangingBeaconsInRegion:(CLBeaconRegion *)region];
        }
    }

    - (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {

        if ([beacons count] != 0) {

            for (CLBeacon *beacon in beacons) {

                //Do something 

            }
        }
    }

Primero creamos  la región, en este caso nos interesan todos los beacons con un determinado UUID, además indicamos que queremos que se nos informe si estamos dentro de la región cuando el usuario active la pantalla del teléfono.

Una vez estamos dentro de la región nuestra aplicación será informada de ello a través del método del protocolo, entonces es cuando empezaremos a tratar de determinar e identificar los beacons cercanos. Si salimos de la región lo que hacemos es parar el “ranging” de los beacons.

Una vez determinados los beacons cercanos, los recibiremos en un array en el método del protocolo “…..didRangeBeacons:inRegion: “ además también recibiremos la región. Una característica importante es que en el array en el que recibimos los beacons estos vienen ordenador por proximidad de mayor a menor, es decir el primer elemento del array corresponderá al beacon más cercano al dispositivo.

Dispositivo iOS como iBeacon

Bien, hemos dicho que un dispositivo iOS puede funcionar como un Beacon, pero que tenemos que hacer para conseguirlo. Pues mucho más sencillo de lo que muchos se esperan, entre ellos yo. Veamos:

CBPeripheralManager *_peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];

CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
                                                                     											major:major
                                                                     											minor:minor
                                                                								identifier:kBeaconIdentifier];

NSDictionary *peripheralData = [region peripheralDataWithMeasuredPower:nil];[_peripheralManager startAdvertising:peripheralData];

 //opcional
 [[UIApplication sharedApplication] setIdleTimerDisabled: YES];

Con estas pocas lineas de código, podríamos hacer que nuestro iPhone o iPad funcionara como un beacon.

Creamos un CBPeripheralManager y una CLBeaconREgion con los valores que queremos que emita nuestro dispositivo, a partir de la región obtenemos el diccionario que nos hace falta para pasarselo al CBPeripheralManager y ya podemos empezar a emitir.

A tener en cuenta: Un dispositivo iOS sólo puede funcionar como iBeacon si la app está en primer plano, en cuanto pase el teléfono a estado de reposo o la app no esté en primer plano dejará de emitir, por eso la parte “opcional” para evitar que el teléfono entre en modo reposo.

Aquí puedes descargar un ejemplo de como hacer que tu dispositivo actúe como un iBeacon.

Opciones para conseguir Beacons

Un dispositivo iOS no nos va ayudar en muchos casos cuando querramos desarrollar una app que interactúe con beacons, por lo que necesitaremos beacons como tal. Actualmente hay varios fabricantes que comercializan iBeacons e imagino que el número crecerá, algunos son estos:

De las opciones de arriba la que me pareció más interesante fue la de Estimote. Aunque en aquel entonces no conocía a la gente de Remote, empresa española que comercializará beacons no tardando mucho.

El beacon diseccionado
El beacon diseccionado

Los Beacons distribuidos por Estimote tienen las siguientes carácterísticas:

  • CPU 32.bit ARM Cortex con 256kb de memoria flash.
  • Acelerómetro.
  • Sensor de temperatura.
  • SDK, realmente es un wrapper de CLLocationManager, CLBeaconRegion y CLBeacon. A parte de ofrecerte una api para modificar la configuración de los iBeacons (No el proximityUUID, viene fijo de fábrica), actualizar el firmaware, modificar la frecuencia de emisión,….
  • Autonomía de 2 años y alcance de 70 metros (en un escenaro ideal, sin interferencias)
  • Es estanco afirman que puede funcionar bajo el agua.
  • Si he de decir, que está en versión beta y el SDK, no permite exprimir al máximo los ibeacons aún.
  • Estimote provee de una api que básicamente es un wrapper del CLLocationManager facilitando alguna de las tareas con beacons.

Aquí podéis encontrar un ejemplo de algunas de las cosas que se pueden hacer con beacons. En este ejemplo se puede alternar entre el sdk de Estimote o de Apple, para que veáis que no siendo para configurar los beacons no es imprescindible el uso del sdk de Estimote.

¿Qué podemos hacer con iBeacons?

Bien, la respuesta a esta pregunta no es finita. Desde que un beacon funciona como una baliza que te permite determinar donde está el dispositivo, pues todo lo que se te ocurra a partir de ahí es viable. Algunos opciones son:

  • Geoposicionamiento “indoor”, crear zonas, proximidad… lo que se te ocurra a partir de la detección de un punto o región.
  • En Passkit, ahora podemos añadir en el json el uuid y el texto a mostrar, el dispositivo detectará el beacon cuando esté cerca de él y mostrará una alerta con el texto indicado.
  • En combinación con el nuevo Framework Multipeer Connectivity, para detectar usuarios o apps, con las que puedas intercambiar información, alertando al usuario de ello.

Ya hay varios casos de uso, algunos son:

Cafeterías que a partir de beacons crean regiones y cuando entras en su establecimiento te da acceso a publicaciones de subscripciones de pago en tu iPad. Una vez sales de la cafetería pierdes ese acceso

Quizás la más obvia de todas, ofrecer descuentos en artículos al cliente que pasa por un lugar específico

En los estadios de Beisbol de EEUU se está haciendo una prueba piloto

Paypal tiene previsto lanzar en el primer trimestre de 2014 un sistema de pago basado en iBeacons

Enlaces de interés

En mi búsqueda de información sobre Beacons he encontrado algunos artículos que me han parecido lo suficientemente interesantes como para compartirlos con vosotros:

Bluetooth Low Energy, Beacons and Retail

With iBeacon, Apple is going to dump on NFC and embrace the internet of things

What’s New in Core Location WWDC 2013

Core Location Framework Reference

Can you Smell the iBeacon?

Reverse Engineering the Estimote

Si quieres que tu Mac actue como un iBeacon, gracias a Laurent Gaches aquí tienes un ejemplo de como hacerlo

Fernando Rodríguez

iOS Developer & Co-Fundador de KeepCoding

Posts más leídos