I canβt say for sure if this is all of you, but I would make the following changes:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Moved to didFinishLaunching... you should not be recreating every time app // becomes active. You can check for locations key in the options Dictionary if // it is necessary to alter your setup based on background launch // Start location services locationManager = [[CLLocationManager alloc] init]; locationManager.desiredAccuracy = kCLLocationAccuracyBest; // Only report to location manager if the user has traveled 1000 meters locationManager.distanceFilter = 1000.0f; locationManager.delegate = self; locationManager.activityType = CLActivityTypeAutomotiveNavigation; // Start monitoring significant locations here as default, will switch to // update locations on enter foreground [locationManager startMonitoringSignificantLocationChanges]; // Hold in property to maintain reference self.locationManager = locationManager; }
Following your example, this will be all that remains in your didBecomeActive method (I would use willEnterForeground ):
- (void)willEnterForeground:(UIApplication *)application { [self.locationManager stopMonitoringSignificantLocationChanges]; [self.locationManager startUpdatingLocation]; }
Entering the background, return to significant changes in location:
- (void)applicationDidEnterBackground:(UIApplication *)application { NSLog(@"Went to Background");
In the delegate method, I recommend taking out all conditional background tests. I wrap the background task ID in case the application is in the background or goes into the background before terminating. I also respond to the global thread, so we are not blocking the UI (optional):
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { UIApplication *app = [UIApplication sharedApplication]; __block UIBackgroundTaskIdentifier locationUpdateTaskID = [app beginBackgroundTaskWithExpirationHandler:^{ dispatch_async(dispatch_get_main_queue(), ^{ if (locationUpdateTaskID != UIBackgroundTaskInvalid) { [app endBackgroundTask:locationUpdateTaskID]; locationUpdateTaskID = UIBackgroundTaskInvalid; } }); }]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
See my project, TTLocationHandler
on Github for a few more examples of using Core Location, how you want to use it.
source share