The last blog post announced the final (and long-awaited) arrival of automatic replies to echoecho on the iPhone.
You may be asking yourself what took so damn long? (I know I certainly was). So I’m going to tell you a story about Apple and background location functionality.
To make things more interesting (and give me an excuse to insert an image) here’s a tool we had to build in order to get this right:
I’ll explain what all this means shortly.
But let me get back to Apple. So as many of you know (well ok – ALL of you that are iphone devs know) Apple now allows background processes on their iPhones in special circumstances – Location apps being one of the primary types allowed to do this.
In fact to quote Apple’s own website
With the new location monitoring service in iPhone OS 4, your app can register for callbacks when the location of the device changes—even when your app isn’t running.
Yeah. Sounds great.
Except it doesn’t work so well in practice. In fact I’d go so far as to say Apple’s implementation of it has been pretty much broken in more ways than one from the very beginning – and even today it’s still not particularly efficient.
Here’s the problem. There are only two forms of background location monitoring Apple expects/allows developers to request.
I’m going to call them CONTINUOUS and SLC.
CONTINUOUS (continuous background location updates in full Apple parlance) is designed for Applications that need continuous access to the onboard Location infrastructure even if they temporarily go into the background (e.g. turn by turn navigation)
Apple explicitly discourages developers from using CONTINUOUS mode longer than is absolutely necessary.
SLC – on the other hand – stands for Significant Location Change – and this is the method Apple recommends.
To wit – from Apple’s website:
The significant-change location service offers a low-power way to receive location data and is highly recommended for applications that do not need highly precise location data.
This would be great. If it worked vaguely – or even at all.
The first problem we had (and btw ANY developer of geoapps on iphone has this problem) is that Apple’s uninstall routine was broken on O/S 4.1. It’s a bug that didn’t receive much attention or PR – which somewhat surprised given that it affected any Geo-App. Essentially it would not allow any app that accessed location services to be re-installed – because it would never uninstall properly in the first place)
But Apple eventually admitted this (I like to think we were among the first to point this flaw out to them) and fixed it in the 4.2 version of the O/S (it was fixed in the 4.0 version – they just broke it in 4.1)
Yes – I know this has nothing to do with SLC directly – but indirectly it does – because it makes the debugging process horrendous. You see Apple has spoiled us devs – because 99% of the stuff works so well that when something doesn’t work we all FREAK out 😉
Back to SLC – the idea here is that when the phone moves a significant distance your application receives an update in the phone’s location.
OK. In theory that sounds good. Less network overhead, less battery wastage – all with one function call.
Like I said. This would be great if it worked. But it doesn’t.
(don’t worry the pictures are coming up)
As regular users of echoecho know – we use a PULL model for requesting location (i.e. other users ask you where you are) which we think is far more sensible, user-friendly and natural than a PUSH model where you spam everyone with your location whenever you choose to check-in (But this belongs in another rant).
The reason we need to background location at all – is because of Automatic replies to your Favorite friends. (as per the previous blog post)
On other platforms (e.g. Android, Symbian or Blackberry) when you get an echo from somebody who is on your Favorites list your phone sees the request come in and then automatically responds on your behalf – notifying you it has done so.
Apple does not allow this particular kind of interaction on the iPhone (more on this later) so the server must respond for you. In other words – we need a reliable, easy and battery-efficient way to update your location if you use the Favorite Friend functionality.
So here (thank god for that because this blog post was getting loooong) are some images describing why this is a problem:
Look at this journey near Hermosa Beach:
The blue circles represent GPS data points and they do a pretty good job of showing where I was at the time of this test. I drove up Manhattan Avenue, took a right down Manhattan Beach Boulevard, a right on Sepulveda and a right again on Artesia/Gould. (we used a custom written diagnostic program on an iPhone 4 and an iPhone 3Gs running in parallel to analyze this throughout the Los Angeles area)
This was approximately an 10 minute journey.
Not bad you might think. Clearly at most intervals there you’d have a half decent idea of a person’s location given that you have so many data points.
Not so fast. These are NOT SLC data points.
Here’s that same image with an SLC data point overlay.
Those would be the big green circles. Yes. There are only two of them – and look how inaccurate they are.
(oh btw – the size of the circle of course indicates the degree of accuracy).
SLC is basically equivalent to cell-id level of accuracy. In other words an accuracy level that predates the very first iPhone.
This sucks. It sucks even more that it doesn’t really work properly.
The phone is supposed to report an SLC event every time it passes into a new Network cell. Well we drove in large 25-30 mile loops around Los Angeles and often there were long 5-6 mile gaps with no SLC events at all. I don’t care how bad AT&T can be at times – it’s not that bad.
The conclusion is basically that SLC is unusable for geofencing, unusable for any kind of friend tracking applications – basically pretty much unusable for most geo-applications we can think of.
So how do you fix this problem?
Well within the Apple constraints there’s only one way – and it’s some variant of what we did – namely:
You use the SLC event not as your location indicator but as a trigger to kick-off high-accuracy location detection (which can then utilise wifi/cell-id AND GPS).
Optimising this algorithm for accuracy vs. battery life still requires a bit of work – but we can’t give all our secret recipes away in one blog post – so that will have to do.
Of course – there is a better way to do this.
If anyone from Apple is reading this I strongly encourage you to implement something which would hardly change your rules at all – and that’s the following:
Allow background running application to be “triggered” by a push notification.
That’s it – it’s a trivial change in code – because when an application is running in the foreground the push notification is passed to the app as an event that the app can choose to process as it pleases.
So this functionality already exists. Apple just needs to allow background running apps to be kicked this way also.
Far cleaner and more elegant.
Not to mention far more efficient – think about the fact that every geo app running on your phone that accesses background location services has to do something like we did to make their solution work.