Significant Location Change Delegate Methods Not Called

All my code is in AppDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]]; _locationMgr = [[CLLocationManager alloc] init]; [_locationMgr setDelegate:self]; if([_locationMgr respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) [_locationMgr setAllowsBackgroundLocationUpdates:YES]; CLAuthorizationStatus authorizationStatus= [CLLocationManager authorizationStatus]; if([launchOptions valueForKey:UIApplicationLaunchOptionsLocationKey] != nil) { NSLog(@"relaunching because of significant location change - restarting SLC"); [_locationMgr startMonitoringSignificantLocationChanges]; } else { if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) { NSLog(@"launching with authorization to always use location - starting SLC"); [_locationMgr startMonitoringSignificantLocationChanges]; } else { NSLog(@"launching with no authorization to always use location - requesting authorization"); if([_locationMgr respondsToSelector:@selector(requestAlwaysAuthorization)]) [_locationMgr requestAlwaysAuthorization]; } } if([userdefaults objectForKey:@"pfuser"] == nil) { NSLog(@"in delegate signup"); SignUpController *signup = [[SignUpController alloc] init]; [self.window setRootViewController:signup]; } else { ViewController *map = [[ViewController alloc] init]; [self.window setRootViewController:map]; } [self.window makeKeyAndVisible]; return YES; } - (void)startSignificantChangeUpdates { deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"START" message:@"startSignificantChangeUpdates called" preferredStyle:UIAlertControllerStyleAlert]; [deviceNotFoundAlertController addAction:deviceNotFoundAlert]; // Create the location manager if this object does not // already have one. if (nil == _locationMgr) { _locationMgr = [[CLLocationManager alloc] init]; _locationMgr.delegate = self; } [CLLocationManager significantLocationChangeMonitoringAvailable]; [_locationMgr startMonitoringSignificantLocationChanges]; } -(void)locationManger:(CLLocationManager *)manager didFailWithError:(NSError *)error { NSLog(@"didFailWithError: %@", error); deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"LOCATION FAIL" message:@"didFailWithError" preferredStyle:UIAlertControllerStyleAlert]; [deviceNotFoundAlertController addAction:deviceNotFoundAlert]; } // Delegate method from the CLLocationManagerDelegate protocol. - (void)_locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"LOCATION UPDATE" message:@"didUpdateLocations called" preferredStyle:UIAlertControllerStyleAlert]; [deviceNotFoundAlertController addAction:deviceNotFoundAlert]; // If it a relatively recent event, turn off updates to save power. CLLocation* location = [locations lastObject]; NSDate* eventDate = location.timestamp; NSTimeInterval howRecent = [eventDate timeIntervalSinceNow]; if (fabs(howRecent) < 15.0) { // If the event is recent, do something with it. NSLog(@"latitude %+.6f, longitude %+.6f\n", location.coordinate.latitude, location.coordinate.longitude); } } 

None of the warnings occur, it looks like delegate methods are not being called.

UPDATE

Now I have:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]]; deviceNotFoundAlert = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]; ... } // Delegate method from the CLLocationManagerDelegate protocol. - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"LOCATION UPDATE" message:@"didUpdateLocations called" preferredStyle:UIAlertControllerStyleAlert]; [deviceNotFoundAlertController addAction:deviceNotFoundAlert]; // If it a relatively recent event, turn off updates to save power. CLLocation* location = [locations lastObject]; NSDate* eventDate = location.timestamp; NSTimeInterval howRecent = [eventDate timeIntervalSinceNow]; if (fabs(howRecent) < 15.0) { // If the event is recent, do something with it. NSLog(@"latitude %+.6f, longitude %+.6f\n", location.coordinate.latitude, location.coordinate.longitude); } } 

When I test the application, I open it at home and then close it, so that when I leave my house, it should send a warning (or 3) at some point, but I do not receive a warning from any of delegate methods (where I posted the warnings).

I just got an idea, maybe I need to display warnings from the main UIViewController , and not AppDelegate ?

Perhaps that’s why I don’t see any warnings: How to add UIAlertController to the application delegate (obj-c)

UPDATE

Here's how I now make warnings:

 deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"START" message:@"startSignificantChangeUpdates called" preferredStyle:UIAlertControllerStyleAlert]; [deviceNotFoundAlertController addAction:deviceNotFoundAlert]; alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; alertWindow.rootViewController = [[UIViewController alloc] init]; alertWindow.windowLevel = UIWindowLevelAlert + 1; [alertWindow makeKeyAndVisible]; [alertWindow.rootViewController presentViewController:deviceNotFoundAlertController animated:YES completion:nil]; 

UPDATE

Warnings did not seem to be a problem; a warning in startSignificantChangeUpdates never appears. Should it appear once when I'm at 500 m from its original location?

UPDATE

Can someone help me figure this out?

The methods of your delegate object are called from the thread in which you started the corresponding location services. This thread itself should have an active loop cycle, like the one found in the main thread of your applications.

UPDATE

I think I understood what was said above, and I have it now - I will test tomorrow.

 ... if([launchOptions valueForKey:UIApplicationLaunchOptionsLocationKey] != nil) { NSLog(@"relaunching because of significant location change - restarting SLC"); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [_locationMgr startMonitoringSignificantLocationChanges]; }); } else { if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) { NSLog(@"launching with authorization to always use location - starting SLC"); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [_locationMgr startMonitoringSignificantLocationChanges]; }); } else { NSLog(@"launching with no authorization to always use location - requesting authorization"); if([_locationMgr respondsToSelector:@selector(requestAlwaysAuthorization)]) [_locationMgr requestAlwaysAuthorization]; } } ... 

I think the code starts the location services in its thread. One thing that I noticed already is that when I exit the application, the place in the upper right corner leaves. I just upgraded to iOS 10. In iOS 9, the location indicator in the upper right corner will remain there, but it will only be a black outline when the application does not work. It may just be something that they changed using iOS 10, or now, because I upgraded to 10, something else is not working now. Or is this what happens when location services start in their thread. From here: Initial iOS background thread

UPDATE

Maybe I'm misusing this thread, but, as I said, now that when I close the application, location services are ending. When I did this without a stream, the location service pointer remained in the upper right corner, like an outline.

UPDATE

I read that the service should be running in the main thread - so now I have:

 CLAuthorizationStatus authorizationStatus= [CLLocationManager authorizationStatus]; NSLog(@"launching with no authorization to always use location - requesting authorization"); if([_locationMgr respondsToSelector:@selector(requestAlwaysAuthorization)]) { [_locationMgr requestAlwaysAuthorization]; } if([launchOptions valueForKey:UIApplicationLaunchOptionsLocationKey] != nil) { NSLog(@"relaunching because of significant location change - restarting SLC"); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [_locationMgr startMonitoringSignificantLocationChanges]; }); } else if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) { NSLog(@"launching with authorization to always use location - starting SLC"); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [_locationMgr startMonitoringSignificantLocationChanges]; }); } else { // } 

The right arrow does not appear when the application is closed, is it something new for iOS 10 where they no longer show?

UPDATE

I accidentally deleted: _locationMgr = [[CLLocationManager alloc] init]; I inserted, and now the arrow is always there, today is going to test.

UPDATE

I tested it, but there were no warnings.

+7
properties ios objective-c background delegates
source share
4 answers

I took my computer with me to my car and watched the console, and I saw that significant changes in location are happening now, because I get location updates every 500 m. Warnings are the only thing that does not work, but they are not related to the program - they were there to see if she worked. It works with this code:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc]initWithFrame:[[UIScreen mainScreen]bounds]]; ... _locationMgr = [[CLLocationManager alloc] init]; [_locationMgr setDelegate:self]; if([_locationMgr respondsToSelector:@selector(setAllowsBackgroundLocationUpdates:)]) [_locationMgr setAllowsBackgroundLocationUpdates:YES]; CLAuthorizationStatus authorizationStatus= [CLLocationManager authorizationStatus]; NSLog(@"launching with no authorization to always use location - requesting authorization"); if([_locationMgr respondsToSelector:@selector(requestAlwaysAuthorization)]) { [_locationMgr requestAlwaysAuthorization]; } if([launchOptions valueForKey:UIApplicationLaunchOptionsLocationKey] != nil) { NSLog(@"relaunching because of significant location change - restarting SLC"); [_locationMgr startMonitoringSignificantLocationChanges]; } else if (authorizationStatus == kCLAuthorizationStatusAuthorizedAlways) { NSLog(@"launching with authorization to always use location - starting SLC"); [_locationMgr startMonitoringSignificantLocationChanges]; } else { // } ... [self.window makeKeyAndVisible]; return YES; } - (void)startSignificantChangeUpdates { // Create the location manager if this object does not // already have one. if (nil == _locationMgr) { _locationMgr = [[CLLocationManager alloc] init]; _locationMgr.delegate = self; } [CLLocationManager significantLocationChangeMonitoringAvailable]; [_locationMgr startMonitoringSignificantLocationChanges]; deviceNotFoundAlertController = [UIAlertController alertControllerWithTitle:@"START" message:@"startSignificantChangeUpdates called" preferredStyle:UIAlertControllerStyleAlert]; } -(void)locationManger:(CLLocationManager *)manager didFailWithError:(NSError *)error { NSLog(@"didFailWithError: %@", error); } // Delegate method from the CLLocationManagerDelegate protocol. - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { // If it a relatively recent event, turn off updates to save power. CLLocation* location = [locations lastObject]; NSDate* eventDate = location.timestamp; NSTimeInterval howRecent = [eventDate timeIntervalSinceNow]; if (fabs(howRecent) < 15.0) { // If the event is recent, do something with it. NSLog(@"latitude %+.6f, longitude %+.6f\n", location.coordinate.latitude, location.coordinate.longitude); } } 
+2
source share

This is a problem with your delegate method, please replace below

 - (void)_locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { } 

from

 - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { } 

Hope this helps you.

+2
source share
 You have written write code, Just add below delegate method in your code. But startMonitoringSignificantLocationChanges for updating location take 10 to 20 min. and also trigger if location channel change. -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { } 
+1
source share

[_ locationMgr startMonitoringSignificantLocationChanges];

The significant location change service provides updates only when significant changes have occurred in the location of devices, for example, 500 m or more.

Thus, your delegate method will be called every time once when your device moves more than 500 meters.

Make sure your application has permission for the background location.

If your application is in the background or foreground, it will call the delegation method, otherwise the application will start with the location option in the AppDelegate file, where you will need to create a Location manager object and start the location again to get a new location.

https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html

+1
source share

All Articles