Hacking with iBeacons: What I wish I’d known

First impressions of what’s possible with iOS and beacons

Sam Piggott
Combo
7 min readApr 12, 2017

--

If I’m being blunt, I honestly thought that getting started with beacons and iOS wouldn’t be too tricky; however, I genuinely found it a bit of a minefield.

Not only that, but the documentation was a bit overwhelming for my simple requirement of “find a single beacon within a meter’s range” test project I was hacking on at the time.

As a result, I thought I’d write up a comprehensive guide to everything I’ve picked up whilst using beacons with iOS. With any luck, this guide should save a good few hours of Stack Overflow sifting for anybody wanting to give beacons with iOS a crack.

Hope this helps!

What are beacons?

Let’s break it down.

  • Beacons are small hardware devices that intermittently send out a Bluetooth signal (usually a few times every second).
  • The distance that this signal can travel is determined by the hardware.
  • The frequency of how many times this signal is emitted a second is also determined by the hardware.
  • The manufacturer should supply a partner app/dashboard where you can connect to your beacon and change these values. For example, my beacons are manufactured by the excellent BlueCats, who offer an app called BC Reveal that allows you to change each beacon’s range and frequency when you’re next to it.
  • Beacons are dumb. They literally just give off a signal. It’s all down to the software on the client side to decide exactly what happens with that signal.
  • You cannot just hunt for ALL beacons that are near your device. You have to specify a region to hunt in!
  • Oh, and a beacon’s signal doesn’t go through water or metal particularly well…
  • …and on that note, guess what most of the human body’s made up of? (hint: it’s not metal). That means if you’re planning on using Beacons in places that are likely to be densely populated (museums, parks, or just anywhere that fellow humans dwell), you’re going to want to put them as high up as possible. Good would be anything above seven feet. Best would be a low ceiling.

How do Beacon Regions work?

Alright, so — a beacon region can be created using just a UUID. No more, no less. Now listen up, because here’s where things get complicated:

  • Beacons ship with three unique identifiers. A UUID, a Minor and a Major value.
  • If a region is initialised with just a UUID, the Minor and Major value will be wildcarded. That means that your app will hunt for all beacons with that UUID, regardless of their Minor or Major.
  • If a region is initialised with a UUID and a Minor value, the Major value will be wildcarded. Same applies if it’s initialised with a UUID and Major — the Minor value will be wildcarded.

As a real-life example, I bought four beacons. All of these beacons had the same UUID and Minor value, but the major value was different for each.

That means I needed to hunt for all beacons with the set UUID and Minor value, but the Major was wildcarded.

How can I start interacting with my beacon?

There are two ways iOS offers to interact with your beacons — through ranging and monitoring. These are both executed from a CLLocationManager instance (startRangingBeacons and startMonitoring respectively).

Ranging Beacons

  • Ranging is like pinging devices. It effectively surveys an area intermittently (in iOS’ case, every second), and comes back with an array of beacons that are within range.
  • You’ll receive a CLBeacon instance when you’re ranging. This has all the information you’d expect; UUID, Major, Minor and RSSI (signal strength).
  • You can do this with as many beacon regions as you wish!

Monitoring Regions

  • Monitoring is like registering a beacon to the device for later usage.
  • That means the device will persist regions you’ve told it to monitor after you’ve started monitoring!
  • Unlike ranging, you can only monitor 20 regions at a time per app.
  • Monitoring gives you the ability to detect when you enter or leave the range of a beacon (also known as transitioning).
  • Unlike ranging, instead of receiving CLBeacon instances in the delegate method, you’ll receive the CLBeaconRegion instead. This means you might need to do some additional digging to identify exactly which beacon has been discovered.
  • However, and probably most excitingly of all, if you have your app closed and wake your device, your device will ping the monitored beacons to see if they’re within range. If they are, your app will open in the background for a few seconds to give you the opportunity to execute some code.

Executing code while the app’s closed/dropped out of memory/in background

A fairly common usage of beacons in iOS is to let the user know that they’re in range of a beacon without opening an app first. This is possible, but comes with its limitations.

  • First, we’ll need to ensure your CLLocationManager instance you use has the property allowsBackgroundLocationUpdates set to “true”.
  • Right. Now, we’re going to want to initialise a CLBeaconRegion you want to monitor, and set its notifyEntryStateOnDisplay property to true.
  • Finally, we’ll startMonitoring (not ranging!) this beacon region.
  • …And that’s it!

Wait; how did that work?

Remember how I said earlier how the device persists the monitored regions? Well, every single time you wake your iPhone/iPod/iPad (not even unlocking!) and Bluetooth is enabled, the device will do a quick pass to see if those monitored regions are within range.

If it finds one, it launches the app quickly in the background, and triggers the delegate method didDetermineState. Neat, right?

Keen to learn a bit more about how this works? We built a little app called Rumblr to test this behaviour out.

Psst: You can find a more exhaustive example over at the Rumblr iOS repo!

Now for the bad news; we can’t force our app to the foreground from this state.

Good news; we can get creative.

For example, we could let our user know that they’re in range of one of our beacons, and prompt them with a notification to open the app!

Gnarly.

Can I figure out how many meters away from this beacon I am?

Bleurgh. Hate to be the bearer of bad news, but there’s no hard-and-fast rule to seeing how many meters away you are. Like I said, beacon signals don’t travel through water or metal, and the distance is typically calculated through signal strength.

With that said, the best way to measure proximity is not from any proximity value — but by using the RSSI. Most beacon distributors will give an idea of what the strength should be at a meter away, depending on what your beacon is configured to. In my case, the manufacturer for the beacons I picked up, BlueCats have a pretty exhaustive list of the expected meter range at ranging signal strengths.

Again — we can get creative. The excellent humans at Wayfindr came up with the genius idea of sending the RSSI proximity trigger over the wire using models (which we ended up taking inspiration from for our own little Rumblr!).

Gotchas

  • Occasionally, a beacon will be ranged (picked up in the didRangeBeacons delegate method). However, the RSSI value is 0. From a few Stack Overflow searches, I’ve deduced that this is typically seen as an incomplete packet. As a result, I perform a check on didRangeBeacons to ensure the RSSI value is anything but 0.
  • Adequate authorisation will need to be given for background beacon-monitoring behaviour. To do this, you can use CLLocationManager’s requestAlwaysAuthorization method to prompt the user. Don’t forget to add the Privacy — Location Always Usage Description property in your Info.plist, too!

Closing thoughts

The next big challenge for Combo and beacon technology is understanding what the best way is to venture between different areas whilst the app is running in the background, as well as the foreground.

On notifyStateOnDisplay — I can totally understand why Apple have limited notifications to only display when the device is woken, rather than just accepting them intermittently in the background — a walk down the high street could end in an abundance of unwanted push notifications, for example. It’s still a touch frustrating — a simple delegate method that was set to ping every minute or so would be fairly discreet and harmless, and certain functionality could be limited to prevent abuse (see aforementioned notification overload).

I’m well excited for what comes next — looks like the people over at Estimote are already pushing the boat out with advanced triangulation, which looks killer.

Everything I’ve explored so far is all fairly simple stuff, but nonetheless, I’ve come away from this really exciting first dive into beacons and their capability.

Hey there! Thanks for sticking around.

Here at Combo, we’re currently working on a gnarly li’l project that harnesses the incredible power of beacons.

It’s called Rumblr, and it’s the only app we know of that gives your studio entrance music using iBeacons and Sonos. We wrote up the whole story over here, but what we learned from beacons alone was worth splitting into its own post — and that’s what you’ve just read.

If you’re keen to see what we’ve been up to, feel free to check out that blog post too!

--

--

Sam Piggott
Combo
Editor for

More than likely found in front of a screen. Making code courses over at CodeSnap.io.