重要的改变位置委托方法不被调用

我所有的代码都在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's 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); } } 

没有警报发生,似乎委托方法没有被调用。

UPDATE

我现在有:

 - (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's 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); } } 

当我testing应用程序,我打开它在我的房子,然后closures它,所以,当我离开我的房子应该发送一个警报(或3)在某些时候,但我没有得到任何代表方法(我放置警报的地方)。

我只是有一个想法,也许我必须显示从主UIViewController警报,而不是AppDelegate

这可能是为什么我没有看到警报: 如何在应用程序委托(obj-c)中添加UIAlertController

UPDATE

这是我现在正在做的警报:

 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

警报似乎不是问题, startSignificantChangeUpdates的警报从不出现。 它应该出现在距离我最初的地点500米处吗?

UPDATE

任何人都可以帮我理解这个吗?

您的委托对象的方法是从您启动相应位置服务的线程中调用的。 这个线程本身必须有一个活动的运行循环,就像在应用程序的主线程中find的一样。

UPDATE

我想我明白了上面的引言是什么意思…我现在有这个 – 明天我会testing。

 ... 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]; } } ... 

我认为代码是在自己的线程上启动位置服务。 我注意到的一件事是,当我退出应用程序,右上angular的位置消失。 我刚刚更新到iOS 10.在iOS 9中,右上angular的位置箭头将停留在那里,但应用程序未运行时只会显示黑色轮廓。 这可能只是他们改变了iOS 10的东西,或者现在因为我更新到10,现在还没有其他工作。 或者当位置服务在自己的线程上运行时会发生什么情况。 从这里开始 : iOS启动后台线程

UPDATE

也许我没有正确使用线程,但正如我所说,现在当我closures应用程序,位置服务退出。 当我在没有线程的情况下,位置服务箭头将停留在右上angular,作为轮廓。

UPDATE

我读到服务应该在主线程上启动 – 所以现在我有:

 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 { // } 

当应用程序closures时,右侧的箭头不显示,这是iOS 10的新东西,他们不再显示它?

UPDATE

我不小心删除了: _locationMgr = [[CLLocationManager alloc] init]; 我放进去,现在箭头总是在那里,今天要去testing。

UPDATE

我testing了它,仍然没有警报。

这是一个与你的代表方法的问题,请在下面更换一个

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

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

希望它会帮助你。

我把我的电脑带到我的车里,看着控制台,我发现现在正在发生重大的位置变化,因为我每500米得到一次位置更新。 警报是唯一不起作用的,但与程序无关 – 他们只是在那里看看它是否工作。 它正在使用这个代码:

 - (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's 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); } } 
 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 { } 

[_locationMgr startMonitoringSignificantLocationChanges];

重大变更的位置服务仅在设备的位置发生重大变化(例如500米或更高)时才会提供更新。

因此,当您的设备移动超过500米时,您的委托方法将每次调用一次。

确保您的应用程序具有后台位置权限。

如果你的应用程序在后台或前台,那么它将调用委托方法,否则应用程序将启动与AppDelegate文件中的位置选项,你必须创build位置pipe理器对象,并再次开始位置获取新的位置。

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