我寫了一個應用程序的監視器用戶的位置。位置服務在我的視圖加載時打開: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。 希望這有助於 –