iOS 7 introduced a new way to detect and monitor location, known as iBeacons. This article gives an overview of what iBeacons are, what they can do, and how you go about setting them up.
iBeacons are low-power, short-distance location monitoring beacons. Any iOS device that supports Bluetooth Low Energy can become an iBeacon, and can detect other iBeacons when they are nearby. Apps can be notified when iBeacons move in and out of range of the device, and can monitor the proximity of iBeacons as their proximity changes over time.
iBeacons enable you to create and monitor location-specific regions on any iOS device that supports Bluetooth Low Energy. They can be used to create many types of innovative location applications:
- A checkout till that displays a customers’ online order receipt as they approach the collection till, and informs them about special offers at that specific store
- A train travel app that knows which train you are on, and automatically starts tracking your train’s live progress as you board
- An indoor location app for a museum that knows which gallery you are in, and provides information about the exhibits in that gallery as you move around
- A conference management system that tracks which sessions you attend as you enter each session, and automatically downloads the session videos to your device once they are published
Any iOS device that supports Bluetooth Low Energy can be turned into an iBeacon. This includes the iPhone 4S or later; the iPod touch 5th Generation; the iPad 3 or later; and the iPad mini.
iOS devices aren’t the only devices that can become iBeacons, however. Third-party hardware manufacturers can create custom hardware devices that support the iBeacon protocol. This enables low-cost embeddable hardware to be created and used as an iBeacon, with full iOS support for beacon detection. Companies such as StickNFind, PayPal and Estimote are already creating cheap iBeacon-compatible hardware.
iBeacons are detected in the background by iOS, even when your app is not running. Your app can register to be notified when specific types of beacon move in and out of range of a device, and can respond accordingly when the current list of iBeacons changes.
One neat feature of iBeacons is that changes in their proximity can be monitored over time. Once you’ve detected an iBeacon, your app can ask Core Location to monitor the beacon’s proximity, and to notify you when that proximity changes.
iBeacons and Geofences
iBeacons (introduced in iOS 7) are not the only way to detect a user’s entry and exit into specific locations. Core Location provides a second method, known as geofencing (introduced in iOS 4). iBeacons and geofences are suited to different use cases, and it is important to decide which is the best approach for your particular app.
When to Use Geofences
Geofences use an iOS device’s onboard location services (such as GPS, WiFi and mobile cell tower connections) to detect when the user enters or exits a specific geographic area in the world. Each geofence region (represented by a CLCircularRegion) is defined as a circle of a specified radius around a known point on the Earth’s surface.
Geofences are an effective way to detect entry and exit into known geographic locations. They are typically used when:
- the region to be detected does not move (i.e. it is a fixed point on the Earth’s surface)
- the region to be detected has a sufficiently large radius (typically over 100m)
- only a limited number of regions need to be detected at a time (typically no more than ten per app)
- the location of all potential regions is known
- the regions to be detected are not multiple indoor locations within a building
When to Use iBeacons
iBeacons use an iOS device’s Bluetooth Low Energy capability to detect transmissions from nearby iBeacon-compatible devices, and to respond to changes in proximity relative to these beacons.
iBeacons are typically used when:
- many different regions need to be detected
- the regions to be detected do not necessarily have a fixed location
- the effective radius of detection is small (typically less than 100m)
- it is useful for each region to identify itself to the device detecting it
- new regions with similar properties may come into existence at a later date
- the regions may be indoors, potentially with several regions in the same building
- users can be assumed to have Bluetooth turned on while detecting regions
Turning an iOS Device into an iBeacon
Any iOS device that supports Bluetooth Low Energy can be turned into an iBeacon, ready for detection by other devices.
Defining Your Beacon’s Identifiers
When creating an iBeacon, there are four properties you can set to identify your beacon:
- an unique identifier known as a proximity UUID, which uniquely identifies a beacon or set of beacons as being of a certain type or from a certain organization
- an internal identifier, for your own reference when identifying this beacon
- a major identifier, to differentiate this beacon from other beacons with the same proximity UUID, and
- a minor identifier, to differentiate this beacon from other beacons with the same proximity UUID and major identifier.
These four properties enable you to customise the setup of your beacons to suit many different use cases.
Uniquely Identifying Your Beacons
An iOS device might have several apps installed with iBeacon support, each of which needs to detect its own specific beacons. One app might be detecting beacons in iPad checkout tills for a particular hamburger store; another app might be detecting trains from a certain train operator. In order for Core Location to differentiate between these different iBeacons, the beacons need to identify themselves as being of a certain type. This is done through a proximity UUID.
A proximity UUID is a universally unique identifier for a particular type of beacon. You can generate a proximity UUID for your beacons using the Mac OS X uuidgen command-line tool. To do so, open a window in Terminal, and type uuidgen on the command line to receive a unique 128-bit string, as in the following example:
$ uuidgen 566C5595-6EC7-4F08-909F-C954BDCA6CD3
You use the same proximity UUID to create your iBeacons as you do to detect them.
In addition to a global proximity UUID, you can also specify a human-readable identifier property (as an NSString) for a given beacon. This identifier enables you to detect different types of beacon within your app’s own code.
Differentiating Between Beacons of the Same Type
Each beacon can be assigned optional major and minor properties, which can be used to differentiate between beacons of the same type. For example:
- the major property might identify different stores in the same chain, and the minor property might identify different checkout tills within a specific store
- the major property might identify a specific train service route, and the minor property might identify a particular carriage number within that train
- the major property might identify a specific gallery within a museum, and the minor property might identify an exhibit within that gallery
The major and minor properties can be used to best suit your own use case, and are optional. The only condition is that you must provide a major property if you also provide a minor property.
Note: the values of major and minor are both stored and advertised as 16-bit unsigned integers. It is your responsibility to define your values in such a way that they can be treated as 16-bit unsigned values.
Creating and Advertising an iBeacon Region
To turn an iOS device into an iBeacon, you must first define a CLBeaconRegion for the new beacon. This is done as follows:
NSUUID *myProximityUUID = [[NSUUID alloc] initWithUUIDString:@"566C5595-6EC7-4F08-909F-C954BDCA6CD3"]; NSNumber *branchNumber = @42; NSNumber *tillNumber = @3; CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:myProximityUUID major:[branchNumber unsignedShortValue] minor:[tillNumber unsignedShortValue] identifier:@"com.mycompany.storetill"];
Here, a new region has been created with a major value of 42 (to identify branch number 42 in a chain of stores), and a minor value of 3 (to identify till number three in that store). The proximityUUID property has been set to the same UUID generated with uuidgen earlier, and the identifier is a human-readable identifier for this new region.
Next, you ask the region to provide some Core Bluetooth-ready peripheral data:
NSDictionary *peripheralData = [region peripheralDataWithMeasuredPower:nil];
This peripheral data dictionary contains all the information Core Bluetooth needs to advertise the new iBeacon region as a CBPeripheral, so that it can be detected by other iOS devices looking for iBeacons with the same proximity UUID.
Note: The code above passes in a measuredPower value of nil. If you wish, you can use this value to specify a calibrated RSSI power level for this new beacon, to vary how loudly or quietly it will be advertised by Core Bluetooth.
Finally, you ask an instance of CBPeripheralManager to advertise this beacon for other devices to detect:
CBPeripheralManager *myPeripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil]; [myPeripheralManager startAdvertising:peripheralData];
Your iOS device is now advertising itself as a beacon!
- The Region Monitoring section of the Location and Maps Programming Guide goes into depth about how to define, monitor and test iBeacon regions.
- The Core Bluetooth Programming Guide describes how to create and manage Core Bluetooth peripherals and peripheral managers.
- The AirLocate sample project from WWDC 2013 demonstrates how to detect and advertise iBeacons from iOS devices.
- Session 307 from WWDC 2013, What’s New in Core Location, demonstrates the capabilities of iBeacons on iOS devices.