Last night I downloaded the Bing for iPad app and it looks quite interesting. However, I ran into a problem that shows a failure for the developers to properly handle an error condition. I told it to use my current location and it said I was over 500 miles away from my home. The location was where I was a few weeks ago. I switched to the Maps app and that app said it was unable to determine the location. A quick device reset fixed everything including Bing, but the fact that Bing didn’t know where I was got me thinking about what caused it. (My WiFi router is registered with Skyhook, so my iPad will always return my house’s location when it asks for the location if I’m home.)
I’ve worked a lot with CLLocationManager and have found some quirks with it. First, sometimes it never returns a value, so developers must set a timer and alert the user. This, however, was not the problem in the Bing app. When the app requests the location, it does something like:
self.manager.desiredAccuracy = kCLLocationAccuracyThreeKilometers;
which means it only needs to be accurate within 3 km. As the CLLocationManager updates its location using:
- (void)locationManager:(CLLocationManager *)inManager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { if (newLocation.horizontalAccuracy >= 0.0 && newLocation.horizontalAccuracy <= 10000.0) { } }
it needs to check the horizontalAccuracy to make sure it is positive and within the desired range. I believe that the Bing app isn’t properly checking this and just taking the value that is immediately returned. Since CLLocationManager caches the last location for efficiency, it is instantly returned. This is the wrong thing to do without checking the result.