Feature_Image_My_beacon_tutorial

iOS iBeacon Tutorial

knowventBanner

You might of heard of iBeacon. It was first used in Apple’s 254 retail stores to increase their customer’s shopping experience. I could go into a debate about how the technology should be used but I am going to focus this article on getting fimiliar with the Apple’s IOS and OSX API. I am also going to show you how to turn your mac or iOS device into an iBeacon itself.

The Technology Ecosystem

iBeacon is part of Apple’s location ecosystem using Bluetooth 4.0 (Low Energy) under the covers. They have neatly included the iBeacon APIs in the Core Location framework. This make total sense since iBeacons are for just that, location information.

There are 3 different iBeacon tooling features you have available to you:

  • Ranging
  • Monitoring
  • Advertising

So what are they and what are their use cases?

Ranging

Ranging allows you to ping iBeacons in your vicinity. During your interaction with a beacon your app will receive a CLProximity enumeration, RSSI (Received Signal Strength Indicator) value and an accuracy value.

NOTE: The current iBeacon implementation will only give you updates of these values every second.

The CLProximity enumeration gives you immediate, near, far or unknown status of the iBeacon in range. This is Core Location interpretation of the distance and gives you a quick metric to use.

NOTE: The proximity value ‘immediate’ seems to only return when the device and the iBeacon are inches away from each other. That leaves you with near and far to discern your proximity. This makes the proximity property irreverent for precision proximity determinations.

The RSSI value is measured in decibels and indicates the signal strength from the iBeacon. This can be used to get more precision on proximity.

The accuracy is a aggregate of the RSSI and the transmitter power. The txPower is calibrated using a known signal strength at 1 meter away.

Monitoring

Monitoring is used when you what the app to be notified when the device enters or exits an iBeacon region. This behaves much of that same way that Core Location’s geofencing behaves.

Don’t expect to get notifications every time. If the device is in the beacon region for only a couple seconds or even a minute or two don’t expect to get an update. Monitoring is very slow. If an application spec calls for notifying a user as they walk by then you may need to use a different strategy.

Advertising

Advertising is used when you want to turn your device into a iBeacon. You define your proximityUUID and major/minor values just as you would with your iBeacon setup.

NOTE: The advertising peripheral functionality is actually apart of Core Bluetooth.

Did You Know…

You can turn your Mac into a iBeacon. Much the same way you can turn advertising on in iOS this can been done one your Mac (must be on Mavericks). Matthew Robinson wrote a blog called Mavericks as an iBeacon. An inspired OSX app BeaconEmitter was written based on it. Special Thanks to BJ Miller for introducing me to this useful app while testing the myBeacons tutorial app.

Setup Your App to Use iBeacon Ranging

As stated above, the ranging feature is tucked into Core Location. You will use the CLLocationManager to range for beacons.


First thing you will want to define your Beacon Region:

-(void)initBeaconRegion
{

    NSUUID *proximityUUID = [[NSUUID alloc] initWithUUIDString:@"7AF66857-FF47-4225-AC7C-B562511DB4CE"];
    self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:proximityUUID major:1 minor:0 identifier:@"MyBeaconIdentifier"];
    self.beaconRegion.notifyEntryStateOnDisplay = NO; //Used for Monitoring
    self.beaconRegion.notifyOnEntry = YES; //Used for Monitoring
    self.beaconRegion.notifyOnExit = YES; //Used for Monitoring
}

This code snippet defines an beacon region with a ProximityUUID, a version set and an identifier. From the Apple Docs

proximityUUID: The unique ID of the beacons being targeted. This value must not be nil.

identifier: A unique identifier to associate with the returned region object. You use this identifier to differentiate regions within your application. This value must not be nil.

major: The major value that you use to identify one or more beacons.

minor: The minor value that you use to identify a specific beacon.


Next, since we will be using the CLLocationManager your delegate class needs to adhere to the CLLocationManagerDelegate protocol using this method:

- (void)locationManager:(CLLocationManager *)manager
        didRangeBeacons:(NSArray *)beacons
               inRegion:(CLBeaconRegion *)region {
      //Handle beacons found during ranging
  }

So, to start ranging iBeacons use:

    [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];

And to stop ranging iBeacons:

    [self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];

Setup Your App to Use iBeacon Monitoring

As mention above, this option is best used for waking up the app when the device enters or exits regions.

Just like above, you will want to define you beacon region

-(void)initBeaconRegion
{

    NSUUID *proximityUUID = [[NSUUID alloc] initWithUUIDString:@"7AF66857-FF47-4225-AC7C-B562511DB4CE"];
    self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:proximityUUID major:1 minor:0 identifier:@"MyBeaconIdentifier"];
    self.beaconRegion.notifyEntryStateOnDisplay = NO; //Used for Monitoring
    self.beaconRegion.notifyOnEntry = YES; //Used for Monitoring
    self.beaconRegion.notifyOnExit = YES; //Used for Monitoring
}

Notice the properties notifyOnEntry and notifyOnExit. These define if the delegate methods are called for this region. Setting them both to YES will ensure the app is notified when both beacon region states are changed.


Next, we will want implement the CLLocationManagerDelegate for the enter and exit region delegate methods.

locationManager:didEnterRegion: – For when the device enters the beacon region

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    //Handle this when the device enters a beacon region
}

locationManager:didExitRegion: – For when the device exits the beacon region

- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
    //Handle when the device enters a beacon region
}

Additionally, the locationManager:didDetermineState:forRegion: is called each time a beacon region boundary transition occurs.

locationManager:didDetermineState:forRegion:

- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
    //The location manager calls this method whenever there is a boundary transition for a region. 
    //It calls this method in addition to calling the locationManager:didEnterRegion: and locationManager:didExitRegion: methods.
}

And, of course, to start monitoring for beacons execute the following:

[self.locationManager startMonitoringForRegion:self.beaconRegion];

To stop monitoring for beacons

[self.locationManager stopMonitoringForRegion:self.beaconRegion];

Having issues with getting monitoring to work? I wrote a troubleshooting guide if you are having trouble getting your app to return didExitRegion or didEnterRegion notifications.

Setup Your App to Use iBeacon Advertising

This process to setup iBeacon Advertising is a little different since it uses the CoreBluetooth framework. Again you will need to define a beacon region. This time it will define the beacon to broadcast, not to look for.

    CLBeaconRegion *region = [[CLBeaconRegion alloc] 
                                        initWithProximityUUID:self.beaconRegion.proximityUUID
                                                        major:1
                                                        minor:0
                                                   identifier:self.beaconRegion.identifier];

You have defined your beacon to broadcast. Now you will need to set your device’s Bluetooth peripheral configuration.

NSDictionary *beaconPeripheralData = [region peripheralDataWithMeasuredPower:nil];

The peripheralDataWithMeasuredPower is the RSSI, measured in decibels, which is the measured strength of the beacon. We are setting it to nil which will use the device’s default signal strength.


Again, to start advertising it is as simple as calling startAdvertising with the addition of the beacon peripheral data.

[self.peripheralManager startAdvertising:beaconPeripheralData];

And to stop advertising

[self.peripheralManager stopAdvertising];

Feel free to download my MyBeacon application which goes with this tutorial.

Let me know if this helped or if you have any suggestions:

Posted in iOS, Mobile, Programming and tagged , , .