Playing with iBeacons on iOS - A Guide
August 7, 2014
Estimated reading time 12 minutes
For the last weeks I’ve been playing with beacons – these are small Bluetooth Low Energy (BLE) devices that broadcast information. iBeacons are Apple’s take on BLE. And i have to say – I’m sold. iBeacons are amazinglysuperduperawesome!
Misconceptions
There are some misconceptions about iBeacons and I’ll start by clearing those up. The only thing a (i)beacon does is broadcast information. Three bits of information to be exact, or to be more exact, three public bits of information (BLE actually sends 5 bit of information, but only 3 are public). A beacon does not get information on the internet, and a beacon does not know it’s own location. Basically it’s a very dumb device which can only say and broadcast it’s name and number.
The information these devices broadcast are a UUID (very unique value), a major and a minor value. (Most of the time) the UUID belongs to the vendor that sells the beacons and most of the time this is fixed in the hardware. The major and minor values are usually set to a default value and can be changes by the developer. (Some vendors allow you to change the UUID as well).
For my experiments I’ve used beacons by Estimote and Roximity. The later were rather useless since none of the major and minor values can be changed. Which is rather important if you want to actually DO stuff. All communication goes through their own SDK/API and CMS. I’ve also found that one of the first calls the API makes (The register call) goes directly to their back-end and send information about all running processes on your device. I send them a tweet and first they responded with this:
@sidneydekoning Hi Sidney! We collect device information to allow our merchants to provide personalized experiences. Email us for more info! — ROXIMITY (@ROXIMITY) July 22, 2014
I mailed them asking them to explain a little bit more about those ‘personalized experiences’ and they replied with this:
There are a number of things that processes on the phone help us with. One example is targeting devices known to have twitter with a deep linked URL or specific twitter based messages. Overall, we are using the data to create segments of customers that merchants can later reach back to, like shoppers or gamers. Often, it’s simply merchants want to target similar customers based on there own data, but using process we can help group them.
I’m still not sure about implementing their API – Maybe their end goal is a buyout with all this bigdata. But that is just guessing. So in the end I decided to go with Estimote. This turned out to be a solid choice. Their support is fast and to the point and their service awesome. (At one point I had to cut open all my beacons to replace the battery)
@sidneydekoning We’re happy to help Sidney, let us know if you need anything 🙂 — Wojtek Borowicz (@Esti_Wojtek) July 29, 2014
So let us get back to beacons.
Development Phase: Proof of Concept
For about two weeks I absorbed all the information I could find and created a proof of concept for a client (A big Dutch beer brand with a green logo – figure it out…). This proof of concept entailed the scanning of six beacons, linking the major an minor values to represent a value in their backend, so when an engineer walks through the brewery they get notified about when machines need maintenance and what specific part needs attention. Pretty fucking cool if I say so myself.
Developement Phase: Architecture
Scanning for beacons is pretty straight forward. For this particular proof of concept the adding of beacons needed to be generic so I could not use the Estimote SDK unfortunately – since their SDK is pretty well thought out, architecture wise.
Using CoreLocation I’ve setup a location manager that manage all the beacons. From a backend call I get a JSON structure with a common name, UUID, major and minor values – this way the app always has the latest beacon description and adding new beacons to the app is a breeze. No need to release an update of the app if new beacons are added/purchased. This also solved my problem with the potential of different beacon vendors and not having to implement every single SDK that is vendor specific. (Yes I could have used the Adapter Pattern and abstracted my code and only have one interface to talk to – but having everything talk directly to the CoreLocation framework seemed like a better choice).
The JSON kindof looks like this:
{
"name" : "My pretty beacon"
"UUID" : "3C074D4B-FC8C-4CA2-82A9-6E9367BBC875"
"major": 54321
"minor": 123
}
After the location manager has been set up and the beacons are registered you start monitoring and then you start ranging for beacons. This is a two step process and I’ll explain what this means.
- Monitoring: You basically tell the system that ‘these are the droids you are looking for’ and depends on the list of beacons you start monitoring
- Ranging: As soon as you enter a beacon region, the ranging allows you to get the distance and proximity to the beacon itself (plus a bunch of other info). So ranging only starts when you enter a region and should be stopped when you exit a region
After the CLLocationManagerDelegate
fires locationManager:didRangeBeacons:inRegion
you can take appropriate action per beacon. Show a UIView, get some data, etc.
If the iDevice is locked/screen is turned off, the background process kicks in and your app is still able to range beacons. If a beacon is found in this way the locationManager:didEnterRegion
and locationManager:didExitRegion
are called, depending on if you enter or exit a region. And to make proper use of this it is considered good practice to show UILocalNotification
.
I’ve found that UILocalNotification does not have a timeout to show the notification on the lockscreen. But with sending out a notification you can also play a sound. One little hack I did is to play an empty mp3 that lasts 15 seconds. Turns out that while this is playing the notification is still showing. So there. Timeout method.
Distance and Proximity
The CoreLocation framework does a lot of the heavy lifting for you calculating distance and proximity. It normalizes the fluctuating values and gives you a rather smooth end result. Even though sometimes there are some false positives. The distance to an beacon is an estimate in meters. This value can fluctuate between 1 meter and 3 meters even though the beacon is located 1.5 meters away from your device. Another property is proximity. This is calculated in region (circles) around the beacons.
One trick to benchmark your beacons is to place them exactly one meter away (use a ruler!) and then check what the advertising interval is and signal strength, then look at the estimated value, and adjust those values to represent a meter.
Learnings
With this there are a lot of thing that I learned, one of the most important is that I assumed that the signal strength would be stable. “Assumption is the mother of all fuckup” still echoes in my mind.
- Apple has a restriction concerning the UDID’s that cannot be circumvented. Per app a maximum of 20 UDID’s can be present.
- The initial setup and monitoring of beacons has a latency of about 10 seconds. Also exiting a region can take some time – this is about 30 seconds and is per Apple’ implementation – sometimes even more. We, developers, have no influence in this, what so ever.
- The actual configuration of the beacons is a very time consuming process as this has to be done per beacon. This process takes about 1.5 minutes per beacon. In a later stage it would be considered more optimal to create an app (desktop and /or mobile) to do this configuration. Or just find one that does.
- The signal of the beacons is, per default settings, not very stable. Playing with the signal strength (RSSI), broadcasting strength and the advertising interval makes this more stable and thus more workable. Try finding the ‘sweet spot’ for your application.
The Room Finder
For another proof of concept I hung two beacons on the doorpost of the meeting- and lunch room in our office and wrote a small app for it ‘The Room Finder’ – it uses iBeacons to show if a room is booked or not. If the room is available you can book the room at the time you desire. If the room is currently booked – You can see who is in the meeting, what the booked times for this room are, the available facilities and if it concerns the lunch room – what today’s special is. All from Google Calendar. Got my inspiration from Robin. This demo took me about 6 hours to build and another 2 to shoot and edit the video. Below is this video.
I hope I’ve given you enough information to start playing with iBeacons yourself. If you have questions leave a comment.
Happy Coding 🙂
PS. Here are some more photo’s of the inside of the beacons. I had to cut them open to replace the battery. Luckily Estimote was nice enough to replace the enclosures.