我写了一个应用程序的监视器用户的位置。位置服务在我的视图加载时打开:IOS:当应用程序在后台停止位置更新一段时间
// Create the location manager if this object does not
// already have one.
if (nil == self.locationManager) {
self.locationManager = [[CLLocationManager alloc] init];
}
self.locationManager.delegate = self;
// Check for iOS 8. Without this guard the code will crash with "unknown selector" on iOS 7.
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startMonitoringSignificantLocationChanges];
NSLog(@"Started monitoring significant location changes");
如果我终止应用程序,而其活动位置服务停止。这是我写的AppDelegate.m停止位置服务的代码:
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also
applicationDidEnterBackground:.
// Saves changes in the application's managed object context before the application terminates.
NSLog(@"entered terminate in delegate");
[myController.locationManager stopUpdatingLocation];
[myController.locationManager stopMonitoringSignificantLocationChanges];
myController.locationManager = nil;
[self saveContext];
}
我遇到了这样的问题:如果我的应用程序已经在后台,上述方法不调用,因此我无法关闭位置服务。要解决这个问题,我发现这个解决方案,我想:
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
UIApplication *app = [UIApplication sharedApplication];
if ([app respondsToSelector:@selector(beginBackgroundTaskWithExpirationHandler:)]) {
self.bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
// Synchronize the cleanup call on the main thread in case
// the task actually finishes at around the same time.
dispatch_async(dispatch_get_main_queue(), ^{
if (self.bgTask != UIBackgroundTaskInvalid)
{
NSLog(@"Marking bgTask as Invalid when we entered background");
[app endBackgroundTask:self.bgTask];
self.bgTask = UIBackgroundTaskInvalid;
}
});
}];
}
}
所以上述方案工作,如果我的应用程序是在后台。但是,我注意到,如果让我的应用程序长时间在后台运行超过五分钟,过期处理程序就会启动。因此,如果我终止应用程序而不将它带到前台。位置服务图标仍会显示在手机上。我必须重新启动应用程序或将其带到前台先终止它禁用定位服务踢代码
如果我删除这两条线:
[app endBackgroundTask:self.bgTask];
self.bgTask = UIBackgroundTaskInvalid;
然后停止位置服务工程在调试器连接五分钟后找到。如果我让它在后台运行时间更长,那么终止代码从不会启动。是因为我没有更改位置或应用程序最终死亡?
所以我的问题是,是否有另一种方式来确保应用程序正确停止位置服务监控,如果它在后台一段时间?
谢谢...荷银
编辑,我做更多的实验,这里是我的发现:
当连接到调试器,如果我等待11分钟不时进入后台模式,该方法willTerminate被调用:
2015-01-13 08:52:45.935 [441:37074] @@@AMRO--->applicationWillResignActive entered
2015-01-13 08:52:46.642 [441:37074] @@@AMRO--->Entered background mode
2015-01-13 08:55:42.697 [441:37074] @@@AMRO--->beginBackgroundTaskWithExpirationHandler called
2015-01-13 09:03:26.265 [441:37074] entered terminate in delegate
如果我试试这个没有调试器,只能等待4分,终止函数不会被调用,我不必等待WH ole 11分钟。
看看这个帖子http://stackoverflow.com/questions/24778492/stop-location-updates-when-app-terminate/24778607#24778607,听起来像一个类似的问题,还有,你打开位置更新背景模式? –
@GuyS是的我需要在后台模式下进行位置跟踪。根据我的问题和实现细节,如果后台应用程序在后台运行超过5分钟,则您提供的堆栈溢出链接解决方案不起作用 –
您确定它是5分钟而不是3分钟吗?在iOS 7后台任务3分钟后停止,我不知道它是否改变了ios 8(我不这么认为)。无论如何,我用这个帖子http://stackoverflow.com/questions/18901583/start-location-manager-in-ios-7-from-background-task获取位置更新在后台,我只是检查,它的位置现在在后台更新20分钟...只需确保添加requestAlwaysAuthorization和plist字符串NSLocationAlwaysUsageDescription。 希望这有助于 –