iBeacon developers are the Matt Damon of coding: incredibly smart, imaginative people but deep down inside they need someone to hug them and tell them “It’s not your fault.”
If you’ve been playing with Apple’s iBeacon(TM) technology you’ll know what I mean. Maybe you followed the tutorial on DevFright and checked out Cocoanetics once you got your Estimote kit; you played around with an SDK or two and checked out how to range your beacons with HiBeacon.
Then you go to test your app and you hit a wall.
But don’t worry: in all likelihood it’s not your fault.
Problem Triggering LocalNotification?
Your app enters a beacon region and is supposed to trigger a local notification. You’re using UILocalNotification with didEnterRegion but it doesn’t seem to work, or it seems to trigger once you leave instead of when you enter.
It’s not your fault: what might seem like an error in ranging is actually just the Apple API taking a seemingly random amount of time to deliver a notification. We’ve yet to define a clear logic for delays: in the same circumstances we’ll see notifications triggered quickly or minutes later.
The second problem is that notifications are being triggered, but they’re being triggered multiple times. But you’ve only walks into a region once! Is there some kind of loop you built into your code?
It’s not your fault: whether you want to blame interference or Apple, your app will randomly trigger a didExitRegion event because it loses the signal. This is almost surely a bug – and has been reported to Apple with no sign yet of a response. (Apple recommends you clear the notification queue once you’ve queued one up for delivery).
So you have your app – you move towards a beacon. Everything is going fine. It shows it as far, then near, then immediate. You’re standing RIGHT NEXT to the beacon. And suddenly it toggles to “Near” again. There must be something wrong with the beacon! Or your code.
No, it’s not your fault: Behind the scenes, Apple is doing some kind of fancy math to average out the signal your app gets from beacons in order to place it within a CLProximity range. But it gets it wrong. And it gets it wrong right after it gets it right before it gets it wrong again. Um, or something. So by relying on Apple’s back-end, unknown logic, you’ll see sudden rapid toggles between proximity regions. This might be due to signal interference but another way to look at it is that Apple has put too high a sensitivity on region changes rather than smoothing out the curve for a slightly longer verification cycle.
My App Doesn’t Seem to Know When It Exits a Region.
Your app responds beautifully once it’s in range of beacons and switches gracefully between CLProximity values. (OK, well, other than the previous point). But then you go to exit a region and your app seems to ‘hang’ for a bit before it knows it left the building.
Guess what? It’s not your fault: Apple might be overly sensitive about CLProximity value changes, but it’s under-sensitive on region exits. While it will toggle unexpectedly between proximity values, it will take its time making absolutely sure you left the region. So, you’ll get a long delay before your app will ‘accept’ that it has truly left a region. Apple says this is a design decision that’s meant to make a seamless user experience.
But Hold On, My App Never Left the Region!
Hand-in-hand with this, however, is that while sometimes it seems like it takes forever to leave a region, it also sometimes unpredictably exits either really fast or when I’m still near a beacon.
It’s not your fault: This is a fairly clear Apple bug. Check out the little “location” arrow on the top of your iPhone or iPad screen. You’ll see it suddenly disappear. A bug seems to randomly turn off location services which can lead to a false positive for either didExitRegion or location services being unavailable.
My App Doesn’t Know Which Beacon to See
Without hard coding some kind of logic around your beacon’s major/minor values (forcing your app, for example, to see them ‘in sequence’ as the user moves through a room) you’re probably relying on something like this to determine the ‘closest’ beacon:
CLBeacon *beacon = [[CLBeacon alloc] init];
beacon = [beacons lastObject];
But even if you’re prioritize “nearest” beacons, you still end up with toggling between beacons, and so you spend all day trying to move your beacons around so they don’t compete with each other. But you STILL have problems!
Sing along now! It’s not your fault: As noted above, Apple does calculations behind the scenes, has problems calculating CLProximity which gives rapid toggles, and has an obscure logic to how it calculates lastObject. This combination of factors, along with room interference, causes all kinds of headaches in prioritizing beacons. You’re not working here with clean logic or technology – so you can expect to work in both code, beacon placement, and beacon settings to get an ideal installation.
My App Won’t Wake Up to Beacons
Location has worked before. I could get my app to do stuff, trigger an alert…but I can’t seem to ‘find beacons’ or even location and get my app working.
It’s Not….Whose? Yes! It’s Not Your Fault Apple has decided, with iOS 7, that what a user REALLY means when they hard close an app is that they really really don’t want that app doing anything. So NO….your app will NOT wake up if it’s closed. It will only work if it’s still in the background (i.e. in the user’s app tray).
Take Heart, Good Will Is What We Need
So take heart: your hunt for the perfect iBeacon app shouldn’t be abandoned before you begin! It’s not your fault that it doesn’t seem to be working the way you expected – and it’s not usually the fault of the beacons either.
List out all these little bugs and weird ways that Apple handles the iBeacon API and design your app against an actual use case. Think through the user experience. Then map that to the known limitations and bugs.
You’ll be surprised how easy it is to handle a lot of this stuff: a clever pushViewController here, a snippet of a timer there, and you’re good to go on the path to iBeacon mastery. Because for all the frustrations you might be having, truly: it’s not your fault.
Any tips you’d like to share? Frustrations you’ve had? Would love to hear them. Drop them in the comments below.
Be the Beacon!