iBeacon Programming: Tips on Ranging, CoreBluetooth and Debugging | Guest Post

iBeacon programming is deceptively simple. But knowing what classes to use in your XCode project is just part of the challenge. Taking advantage of the extra ‘packets’ in Bluetooth, understanding how far a beacon ranges, and how to use advertising identifiers can challenge even the most experienced programmer.

In this guest post by Richard Bown of Xyglo BV, we find some unexpected insights into how beacons work and how developers can benefit from them.

Your Phone is a Beacon: Using App Pairing

I’ve been recently investigating the properties of iOS7 iBeacon development while working on my first iBeacon app – VoucherThing. While a lot of people are looking to implement bespoke hardware beacons or implement off-the-shelf solutions for retailers I was more interested in the software possibilities. I also know that I could turn my iPhone and iPad into an iBeacon so I saw that as the path of least resistance to iBeacon nirvana!

My starting point were some of the excellent example iBeacon app pairing projects. The concept of these are simple – download the example, build the apps from the projects in Xcode, send them down the wire to your test devices and then you can be up and running and testing ranging in no time at all. And immediately you’ll notice how the range of the iDevices can quickly get diminished in busy or crowded environments. You may have heard some bold claims for BLE and iBeacon but these are very dependent on surroundings.

Home on the Range

In the iOS code, iBeacons are set up in a similar manner to CoreBluetooth services except the service setup calls require a Major and Minor company identifier to be specified in both the sending (Peripheral) and the receiving (Central) device. These identifiers will fire off the appropriate delegates to match entering and leaving of iBeacon zones around the device. For anyone who’s built an iOS app before none of this will cause too much of an issue.

iBeacon ranging splits the world into four areas – Near, Mid, Far and Out Of Range. From my testing in the house and in office environments using an iPad Mini and an iPhone 4S the distances appear to stack up a little like this – although your mileage may most definitely vary!

Near – touching -> 20cms
Mid – 20cms > 5-10m
Far – 5-10m+
Out of range – 20-30m+

These figures vary per environment but they certainly fell a bit short of my initial expectations. In retrospect though and considering what iBeacon gives you I’ll take this is a starting point, and bear in mind that these ranges are only likely to improve and get probably get more accurate.

Wake Me Up

One of the great things about iBeacon is the ability to get apps to send user notifications on range boundary changes. When an iBeacon comes into range the iDevice owner can be notified with a message if they’ve enabled notifications and location services – for example they can be told to go and visit the retailer assuming you have that particular app installed.

This can be very useful when using pairs of apps – with VoucherThing there is a customer app and a merchant app. Both act as iBeacons and both can detect each other – this means we can implement a ‘radar’ type of user interface which tells the user of either how many customers or how many merchants are in the area, both apps also get notifications when customers or merchants come into view. Also due to the way that iBeacon is implemented in iOS7 notifications occur even when the app is backgrounded.

Never The Twain: Core Bluetooth

During experimentation with iBeacon I also wanted to try and transmit extra information (merchant logo and information) alongside my beacon. As far as I’m aware you can only transmit a few extra bytes of information along with iBeacon – not enough to transmit image data in any meaningful period of time. Also after some trial and error with the CoreBluetooth API it appeared that I could register both iBeacon and normal core bluetooth transfer services simultaneously but not both services would actually work.

To workaround this limitation I decided to poll these services – offer a few seconds of iBeacon paging, then tear that connection down and then transmit merchant information over CoreBluetooth services. If the apps are set up correctly to handle this type of polling elegantly then the user experience is seamless and this works pretty well.

Not Reporting

While developing I was using iOS 7.0 and 7.1 – both known to have some iBeacon disconnection issues (as I was to find out later) and both seemed to need a hardware reset of the devices to get ranging working again. Despite this I was confident this issue would be eventually resolved by Apple and the recent 7.1.2 update is purported to have much better iBeacon stability.

In Summary

For those looking to get into the nuts and bolts of iBeacon I can’t recommend highly enough the example projects out there on the internet to get started. Bear in mind that some versions of iOS prior to 7.1.2 will have problems disconnecting or not connecting with iBeacons – they will work and then stop working sporadically and only a hardware reset of the device will allow you to start ranging again (turning bluetooth on and off doesn’t work). However if you have two iOS devices and can easily debug them both you can get a great idea of how iBeacon ranging and range changes work. It’s simple, it’s intuitive and the possibilities are intriguing.

Share Your Thoughts

Join our weekly e-mail list for more on iBeacons. Join the conversation on Twitter, or connect with me on LinkedIn.

iBeacon Tutorial from the King of Tutorials

iBeacon Tutorial Haz Cats

 

An in-depth iBeacon tutorial has been posted at the textbook site for XCode and iOS development: Ray Wenderlich.

Other tutorials may be, shall we say, more modern looking. Appcoda amd DevFright both provide neat, clean overviews of how to code an app to work with the Apple iBeacon framework.

But there’s something about tutorials on Ray Wenderlich that edge just slightly enough into being overly geeky to make them challenging but incredibly useful.

The author, Chris Wagner, outlines basic information about what a Bluetooth LE powered beacon is and then gets to experiment with beacons from KSTechnologies (an often unrecognized manufacturer of beacons which has been spotted under white label at other companies).

The tutorial takes you through all the basics – and assumes some familiarity with how a TableViewController, helper methods and other basics of XCode. He demonstrates how to range beacons and to loop your found beacons against those in your array and shows how to properly execute notifications on region exit.

It’s a nice solid tutorial from the king of tutorials and even for those experienced with beacons is still worth a look for the way Chris solved a few little challenges along the way (such as the lastSeenBeacon helper class).

Share Your Thoughts

Join our weekly e-mail list for more on iBeacons. Join the conversation on Twitter, or connect with me on LinkedIn.

Any tutorials you’ve seen that proved especially helpful? If there were other iBeacon tutorials that pushed us in new directions, what would they cover?

Apple iBeacon Bugs Complicate Bluetooth LE Experience

Before you attack your new Bluetooth LE beacon in frustration you can blame a possible bug in the Apple API for sudden state changes in finding and ranging beacons.

After banging our own heads, Dan Nolan from Proxima confirmed a problem we’d been seeing and which we initially blamed either on the beacons themselves or interference of some kind.

Namely:

  • Your app is likely to lose range of beacons for brief instances and will briefly report didExitRegion before quickly returning to being in range
  • Your app will sometimes make the wrong ‘guess’ as to which proximity region it’s in before eventually correcting itself. It will sometimes report Proximity == near when you’re “immediate” or “immediate” when you’re “near” and then flip itself back to the correct value.

The bug is hard to nail down because Apple hasn’t documented the logic behind how it’s API works and doesn’t tell us how, exactly, they calculate proximity (which is a kind of rolling average and calculation based on signal strength and the accuracy packet). There are two key steps that your app will take in “finding” beacons:

Ranging Beacons
Using didStartMonitoringForRegion your app will ‘look’ for beacons while open or in the background tray. Once it finds them, you can initiate an action with didEnterRegion.

This one is simple enough and while the response time varies depending on whether your app is in the background or foreground and, weirdly, how long your app has been open or whether you’ve recently ranged, it works well enough.

It’s how the app monitors leaving a region that makes things complicated. With didExitRegion the API is ‘smart’ enough to delay itself when you leave a region to make absolutely sure you’re gone. Usually, this delay seems to be 3-4 seconds, whereas it will detect a proximity change in 1 second or under.

Phone and beacon stay in a fixed position and then this happens...
Phone and beacon stay in a fixed position and then this happens…

However, the bug we’ve run into is that your app will sometimes say that you’ve left a region and then immediately correct itself. This might be due to signal interference. Using HiBeacon or other beacon monitoring apps, we’ll see brief “cutouts” in power displayed – but our suspicion is that there isn’t an actual cut-out, it’s the detection that’s the issue.

What’s strange about the bug is that under ‘normal’ conditions, the app won’t report didExitRegion until it’s confirmed that you’ve actually left. But in the issue of the bug, no confirmation happens – it just “exits” itself from the beacon region and then immediately flips back.

Beacon Proximity
As noted above, your app will sometimes make the wrong guess as to which region it’s in. Using CLProximity, the API seems to have been set up to correct itself as more data comes in. Your app may be right next to a beacon and it will ‘guess’ that it’s near, but then correct to immediate. But these corrections aren’t predictable. And when the app is guessing “immediate” but you’re actually “near”, you can have weird decisions to make about the user experience.

One time you put your app next to a beacon and it pushes a coupon, the next time it pushes an ad for shoes. Not at least being able to predict what factors will help the app get it ‘right’ is frustrating to say the least…and it’s either an out-and-out bug or a flaw in the logic behind the scenes.

What to Do?
The work-arounds to these issues all feel like hacks. Instead of the Apple API gracefully moving between finding and leaving regions and coming into proximity of beacons, you need to insert additional logic to avoid rapid ‘toggling’ and to ‘fix’ the last beacon reading in the case of a brief didExitRegion call. Dan and Apple itself have suggested that CLProximity won’t be the API you want to use if you’re really putting beacons through their paces: and you’ll need to calculate proximity based on RSSI and accuracy from the beacon advertising packet.

We’ve tested this on three different types of beacons, so it doesn’t seem to be related to the manufacturer of the beacons.

But have you seen similar results to those above? Are they “bugs” or just the reality of beacons which needs to be corrected for with code? Let us know in the comments below or drop me an e-mail.

Jump Onto Our Mailing List

Let’s chat on Twitter! We have some good conversations. Or join our weekly mailing list for ‘BEEKn unplugged’ – I rant a little each Friday and share stuff that doesn’t make it on the site.

Be the Beacon!

Estimote Quick Tip: Edit Major/Minor and Other Device Properties

Estimote Editor
Estimote Editor

A short and incredibly sweet tip if you recently got your hands on a set of Estimote Bluetooth LE beacons: run, don’t walk and grab yourself a copy of the Estimote Editor.

It’s a sweet little piece of code that lets you quickly change the settings on the physical beacon (e.g. major/minor and other values). Just tap the editable values (highlighted in blue) and an editor pops open allowing you to change the setting.

(It does note, however, that although power seems to be an editable value “the API appears to be broken” according to the developer of Estimote Editor).

Was thrilled to find it!