Building an iBeacon App
So you’ve decided you want to take the plunge into the pool of hyperlocality by adding iBeacons to your app. Here’s what you need to know:
- Not all beacons are iBeacons. iBeacons are better. Beacons broadcast (generally Bluetooth) unique identifier numbers. Apple provides support for iBeacons by recognizing them and knowing their range. Apple will continue to monitor for beacons if an app is not running.
- Make your feature compelling enough to get the user to turn on their bluetooth and location. You get one chance to ask for permission, choose wisely.
- iBeacon monitoring is actually quite battery efficient, but the tech media has been telling people otherwise. Make sure your app clearly indicates the battery efficiency and encourages them to leave bluetooth on.
- Protect your users’ personal info. Beacon regions count as location, even if it’s latitude & longitude.
- Bluetooth beacons are radios. Radios are messy. Test and calibrate the signals to ensure the best signal reliability. Signal conditions vary over time, deployment locations, and manufacturers.
These are just some of the challenges in beacon-enabling an app, but we’re here to guide you through them. At Kinvey, we recently built an app for Gluecon – a conference for cloud, mobile, and big data developers – to facilitate meetups between attendees based on both common interests and proximity (which was determined via beacons). Despite being an experienced iOS developer, I encountered some challenges that I hadn’t previously due to some unique traits of beacons. The following is a more detailed description of how we encountered and solved these challenges. We hope you’ll be able to learn from our experience and make great iBeacon-powered apps.
Challenge #1: Choosing Features
Beacon technology allows your app to approximate its physical distance to the broadcasting beacon. If the beacon itself is at a known location, then you can get an idea of where the user is within that measured radius. Beacons can also be tied instead to another device or movable fixture such as a balloon, train car, stadium seat section, etc. If the app already knows the identity of the user, now you have a mapping between the user and the beacon. With a backend to coordinate this mapping, you can link information about the beacon, its real world context, and the user, allowing you to aggregate a very specific context of the user: a very precise location, time, and application context. For example, you discover which beacons are visited by the user, for how long, and in what order. You can also push information about the beacon to the user based on the time (e.g. a limited time coupon), user preference (modernist vs impressionist paintings in a museum), or based on current conditions (show users to less crowded checkout lines, inform about nearby friends). Fig 1. The server can serve as intermediary between the beacon, knowledge about the beacon (such as is its location), and the user
Given access to all this context, you have to choose features that improve the app’s user experience, while still being realistic, protective of user trust, and if possible, still function without the beacons. With our Gluecon app we came up with the desired list of features:
- Connect users with similar interests to meet up, network, and learn from each other
- Provide information about vendors when the user walks up to a booth
- Interact with users and vendors through messaging tied to the booth
From this list we had to narrow down our booth-based use cases because we weren’t able to source enough beacon devices to have one per booth. When choosing features, it’s important to keep in mind that when the app is in the background, even if it’s killed, the device still monitors for the presence of beacons (this is known as region monitoring). Only iBeacons can be monitored in this way; if you use another type of Bluetooth beacon, the app needs to be active to search for them. Also, support for Android and other mobile platforms is still emerging by the open source community, so it’s hard to plan any particular cross-platform feature set.
Challenge #2: The Permission Matrix
Another challenge of using iBeacons is that the user needs to grant location permissions in order to use the feature. On top of needing the permission, an app has to be aware that only certain devices support the beacons and device’s Bluetooth has to be turned on. This means there are several states for the app to check before beacons can be successfully used.
Fig 2. The iBeacon Permission Matrix
- “Location Services” is the overall checkbox in the “Privacy” setting.
- “App Authorization Status” is the result of the user pressing allow/deny in the location permission popup. This is shown automatically when the location is first requested.
- Ranging depends on the the device having Bluetooth Low Energy (BLE) capability and that capability being enabled in settings
- Beacon region monitoring depends on having BLE, Bluetooth turned on, and having background capabilities enabled.
Assuming the device is iBeacon capable iPad (third generation), iPad (fourth generation), iPad Air, iPad mini, iPad mini with retina, iPhone 4s, 5, 5c, 5s – the first challenge is convincing the user to enable Bluetooth and location services, and specifically give your app permission to access the device’s location. This is true even if the device doesn’t use GPS or WiFi-based location (since beacons can be tied to real world location). In order to provide the best experience, you should wait until the last possible moment to ask for permission, instead of blasting users up front, before they’ve even tried your app. For example, our app doesn’t request location until after login and setup are complete, when the main screen goes to display the beacon information. One thing we could have done to delay asking even further, would have been to only start detecting beacons when the conference is about to start (instead of at the app’s first launch), since the app is only useful during the actual conference. It’s also important to have good explanation text. This can be set in the application’s Info in the Xcode’s target editor as a privacy string. This text helps the user trust that the application needs it for a good purpose and that you’re not abusing the information. This text should describe what they’ll get out of the information and how you’ll use it. Fig 3. The explanatory text in the location permission dialog
For our app we’ve taken a tip from Cluster and pre-ask the user for permission. If the user declines, we save the response and time in the app’s user preferences, and try again at a later interval, waiting about six hours to see if using the app has changed their mind. Remember, that once the user presses “Don’t Allow” from the system dialog, there is no way to re-ask. The user has to delete and reinstall the app, or reset the permission in the Settings app. The other issue to deal with is that users have been under the impression that Bluetooth and location services drain battery. In fact, beacon monitoring is extremely energy efficient … significantly more so than using GPS (that’s why it’s called Low Energy). iOS will manage its monitoring by aggregating scans and dynamically changing its polling interval depending on context and remaining battery. We all need to educate users to leave these settings on. At Kinvey we’ve extracted the code for checking and managing all these permissions into a generic iOS library: https://github.com/KinveyLabs/KCSIBeacon And finally, be sure to keep your app viable even when beacon information is not available. Depending on the app here are some strategies:
- Fall back to coarse location using GPS (if the beacons have a known location)
- If the app automatically takes an action when the user approaches a beacon, such as a museum exhibit, point-of-sale system, or conference room, you can let the user manually select their spot from a list.
- If an app is based around sharing location, allow the user to control when that information is shared. For example, our conference app has a timed “Incognito” mode, where the user can choose to temporarily stop sharing location. This way they don’t have to leave the app to disable permission and maybe never resume sharing.
Challenge #3: Hardware
Many apps are developed as closed and nicely-behaved systems; either a button is pressed or not, an item is found in the database or not, etc. But when using beacons, you have to be aware that you’re dealing with external radios. Fortunately, the iOS SDK deals with all the intricacies of detecting the signals, decoding, error correcting, etc, and just presents the beacon identifiers in a CLLocationManager callback. Implicit in this procedure is that the device is making a best guess at what it perceives the beacon’s distance to be based on the difference between measured and broadcasted power and changes in the signal over time. The measured value is affected by how the radio waves bounce around the room, and, importantly, is very much affected by the big fleshy bags of water known as users. The bluetooth LE spectrum is also in the same spectrum band as WiFi and other wireless devices, which can interfere with the signal. And most unfortunately, the signal quality depends on the broadcasting device (and we’ve found quality to vary wildly among manufacturers). Beacon signals are affected by temperature, device power, the difference between described power and actual power, and polling interval, which may vary from broadcast to broadcast. What all this boils down to is that signal accuracy is highly variable. This is why the SDK describes the distance in gross categories: Immediate, Near, Far, (and unknown). Along with this value the accuracy and power measurements are provided to the app in order for it to make the best choices when determining when to act on this information. Fortunately, when using beacon regions for monitoring entrance events, this is pretty easy – once the device detects the beacon it’s considered inside the region (and some beacons can broadcast tens or even hundreds of meters). Exiting a region is a bit more complicated, since the device can’t rely on just missing receiving signals, as broadcasts can get dropped in good conditions. Therefore it can take several minutes after the device leaves the broadcast zone to be considered outside the region. For our use cases it wasn’t enough to just know which region the app was in, since the regions overlap (there are multiple beacons in the broadcast zone). We wanted to know which of multiple beacons is the “nearest”. “Nearest” is in quotes because this is a best guess based upon the location information provided by the SDKs. This involves comparing all the beacon range measurements over time to find the find the one with the best accuracy and closest measured distance.
Challenge #4: Triangulation & Tracking
Once the app calculates the nearest beacon we can then associate the beacon with a user and say “this user is at this beacon.” For example, in the following scenario, even though the user is within the region for three beacons (B1, B2, and B3), we want the app to think he’s at B1, which is the one he’s closest to in the real world. Fig 4. User is within range of three beacons; we want to determine which is closest based on the strongest signal
Once the nearest beacon is determined the app can present its important contextual information. In our app’s case it is a list of which other users are that beacon. For this we have to rely on a backend to coordinate the linking of users to a specific beacon and then showing those users to each other. This two-way communication is a problem with beacons. Beacons are one-way devices, so they don’t know about the devices receiving their broadcasts. There are two ways to work around this. The beacon device itself can open a second channel to communicate with the phone and then transmit that data back to a server using a persistent network connection. However, this functionality is not part of the iBeacon specification, and only a few manufacturers make devices capable of this. These extra communication channels also drain a lot battery, limiting how long they can be in the field, or where they can be placed (if needing a network and plug). The easier way is to fake it by making the app do the work. Presumably the app already has a connection to your backend to get information about the beacon, so the app can just update a record and say “I’m here”. Now you know where the user is and when. This information can be used to personalize the app or real-world experience, optimize room layout, or adjust resources in real-time. For our app we aggregate data to count the number of unique visits to a beacon within a 30 minute time period and share that data in the app through a screen of bar graphs. Fig 5. The bar charts show how an aggregate of nearby users over time. The letter/number titles are internal designations for the beacons (UUIDs are so hard to remember)
Challenge #5: The Server Piece
We used Kinvey (obviously) as the glue that links beacons to their real-world location, users to beacons, and users to users. Our app has one data collection that lists each beacon with its short name, UUID, major and minor numbers, as well as some metadata, like its location on a floor plan. These are pulled by the app when it launches. When the app encounters a beacon, it looks up the beacon’s document from this table and displays the appropriate context to the user. In addition, we also update the user object with the beacon identifier and timestamp in a “last beacon column.” Then we have a business logic script that the app can query to get a list of all the users at a beacon. This script filters the data for privacy and tries to interpret what “at the beacon” means. Determining presence at a beacon is tricky in the real-world because update events might not make it to the server and because beacon ranging can be dropped by an iOS device. Our business logic uses a time-based heuristic to guess if the user is reasonably still there. That is, if the user was last recorded at the specified beacon within a short (5 minute) window and didn’t move to a different beacon, the user is counted as actively at the beacon. The application shows a list of nearby users. This list allows the user to see the nearby users along with their interests. If there is a match, they are able to message each other to meet up and discuss cool technology. This messaging is done through yet another data collection, and Kinvey brokers the updating of each client and sending push notifications to the device. In addition to the real-time data, unique visitors are binned with a separate set of business logic scripts to provide the data for the bar graph view. This allows us to observe trends, perform statistical analysis and draw conclusions. In our original design we wanted to be able to determine the “most popular” booths at the conference. But with the scaled back app we will be able to observe the most popular presentations in the breakout rooms.
Challenge #6: Getting Through the App Store
For us the final challenge was navigating the app store review process. We had to resubmit the description and metadata a few times. Here’s what we learned:
- It’s important to explain clearly what the app is doing, both in the public description and in the review notes.
- We were asked for a video demonstrating the use of beacons in the app, since they weren’t able to set up our mock conference floor. We used the Reflector app to capture a screen video and Camtasia studio to annotate the video. We included a link to the video in our review notes.
- We provided a demo account and some beacon UUIDs in the review notes to help the reviewers.
- Since the app uses background location monitoring, we had to include a battery use disclaimer in our description. “Continued use of GPS running in the background can dramatically decrease battery life.
Using beacons in an app requires managing user expectations and permissions, coding defensively against unpredictable hardware conditions, and providing a way to link the beacon identifier with something useful in the application. Using iBeacons introduces a bunch of messy moving parts, and it’s important to follow the best practices. We hope you’ll be able to learn from our journey. You can check out the source code for our app at https://github.com/KinveyApps/Who-s-At-Glue, and our iBeacon management library at https://github.com/KinveyLabs/KCSIBeacon. Happy coding!