iPhone Location Data doesn't work on very first start
I'm experiencing a strange issue with location on iPhone. It looks just crazy but it seems to be reproducible. In my application I use Core Location to get location data on some user actions. Usually it seems to work. But on the very first run after the app was deployed on device without previous version (doesn't matter from XCode or via iTunes), it doesn't work at all. Neither
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
nor
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
are called. I don't even get coordinates of cell towers. The only sign that GPS is working is pop up that asks to allow access to location data. If I quit application (and by quit I mean really killing it instead of just putting into background), on next run everything usually starts working just fine.
Some more details. As I need to get locations of where user does certain actions, I use following approach:
- I use the same shared
CLLocationManager
object (withkCLLocationAccuracyBest
) and the same shared delegate object. - When user does the action, I call
startUpdatingLocation
and create a background thread, basically timer, but there is something more not related. It wakes up once every 15 seconds - I accumulate fixes received by
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
- When background thread is waken up, it checks fixes and time. If there is a good enough fix, it stops waiting. If 1 minute time interval is exceeded, it stops waiting as well.
- "Stops waiting" = calling some method. That method seeks for best fix among received (if any) and processes it. Also it calls
stopUpdatingLocation
I don't see any obvious flaws in th开发者_C百科at way. And moreover, the very same binary usually starts working on second start. Any ideas why? Am I going crazy?
It seems that I found the answer myself. My application requires some start up preparations. The difference was that at the very first run I do some big one-time job (some big synchronization over network). This long task is done in background thread. The same thread then does "common initialization" including creation of CLLocationManager object. Of course, background thread then quickly dies leaving CLLocationManager without any RunLoop. On the second start there is no need in big synchronization and "common initialization" is performed on UI thread. Therefore CLLocationManager is running on the main RunLoop and happily delivers fixes.
To sum up: when you create CLLocationManager object, it is vitally important to do it on right thread (or rather NSRunLoop/CFRunLoop).
精彩评论