[iBeacon] Envoi de notification locale quand on rentre dans une région

mercredi 25 juin 2014

Voici un petit tutoriel pour détecter si on est proche d’une région de beacons et de recevoir une notification local pour avertir l’utilisateur qu’il est proche d’un lien déterminé par un beacon et via la technologie iBeacon d’Apple basée sur le bluetooth LE.

background

Tout d’abord, il faut activer le background mode et plusieurs options:

  • Location updates
  • Uses bluetooth LE accesoires
  • Acts as a Bluetooth LE accessory
  • Background Fetch
  • Remote notifications

Ensuite dans le Appdelegate, il faut inclure le framework #import pour avoir accès aux fonctions delgate de CLLocationManagerDelegate

Dans le Appdelegate.h

#import <CoreLocation/CoreLocation.h>
@interface UCHAppDelegate : UIResponder <UIApplicationDelegate,CLLocationManagerDelegate>
@property (strong, nonatomic) UIWindow *window;
@property CLLocationManager * locationManager;

Dans AppDelegate.m fonction – (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

// Dans mon cas les ibeacons sont encodés dans un fichier plist    
NSArray * beacon_plist = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"beacons" ofType:@"plist"]];
    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    CLBeaconRegion *region;
    NSDictionary * item;
    for(item in beacon_plist){
        ibeacon *tmp = [[ibeacon alloc] initWithDictionary:item];
        region = [[CLBeaconRegion alloc] initWithProximityUUID:ESTIMOTE_PROXIMITY_UUID major:tmp.major minor:tmp.minor identifier:tmp.estimote_id];
        region.notifyEntryStateOnDisplay = YES;
        region.notifyOnEntry = YES;
        [locationManager startMonitoringForRegion:region];
        [locationManager stopRangingBeaconsInRegion:region];
    }

Attention:il est impératif de définir la région à « monitorer » dans le la fonction didFinishLaunchingWithOptions de l’AppDelegate si vous souhaitez recevoir les notifications locales même si l’utilisateur n’a pas l’application en background!!

Dans ce cas chaque région comporte un beacon car je veux détecter quand on rentre dans une région qui sont éloignées l’une des autres.

Maintenant voici la fonction qui envoie les notifications quand on rentre dans une région:

- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
    UIApplicationState appstate = [[UIApplication sharedApplication] applicationState];
    if(appstate != UIApplicationStateActive){
        if(state == CLRegionStateInside) {
                UILocalNotification* localNotification = [[UILocalNotification alloc] init];
                localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:2];
                localNotification.alertBody = [NSString stringWithFormat:@"Bienvenue dans mon magasin"];
                localNotification.timeZone = [NSTimeZone defaultTimeZone];
                localNotification.soundName = UILocalNotificationDefaultSoundName;
                [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
        }
    }
}

Dans ce cas-ci, les notifications ne sont envoyées que si on est pas dans l’application. Que l’application soit en background ou non (sous IOS 7.1).
Attention: il faut rajouter une condition avant l’envoi de la notification pour s’assurer de ne pas envoyer des notifications tout le temps ce qui peut être nuisible!
J’ai aussi remarqué que la détection des beacons sera plus rapide et plus précise quand on est dans l’application avec la fonction didrange que celle de didDetermineState qui tourne même en background.

Un autre point intéressant dans cette fonction, c’est qu’il est possible de faire appel à un webservice dans cette méthode pour par exemple rechercher le contenu de la notification sur un serveur distant.

Pour finir, il reste la fonction qui est appelée lorsqu’on reçoit la notification en background ou non.

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
// GOTO SCREEN 
}

Pour les ibeacons, il existe deux type d’action:

  • Monitoring:cette action permet de déterminer si un device entre ou quitte une région, idéal pour l’utilisation en background
  • Ranging:cette action permet de définir la distance (immédiate,proche,loin) d’un ibeacon. Cette activité ne tourne pas en background.

Tags: Bluetooth , ibeacon