我們目前正在開發一個iOS應用程序需要在後臺檢查位置。起初,我們試圖使用顯着的位置變化,但它們不夠準確/不經常觸發。我們考慮過使用區域監控,但是從我在線閱讀的內容來看,這並不總是準確的,而且您還有一個監控區域數量有限的問題。 (我們最終可能會嘗試區域監控)。但是,目前我們正試圖使用標準位置更新來跟蹤用戶在後臺的位置,並計劃每隔5分鐘檢查一次。後臺任務似乎並沒有被取消/結束
的應用程序註冊爲位置更新在後臺(使用「應用程序註冊了位置更新」爲「所需的背景模式」),和我們啓動一個後臺任務,一次檢查位置,停止位置更新,然後使用NSThread sleepForTimeInterval:
到(目前,我們正在開發中)暫停任務10秒。然後,它再次檢查位置,停止位置更新,暫停10秒,等
這似乎按預期方式工作......當應用程序進入後臺,我們收到日誌/通知我們的位置更新每10秒鐘一次,當應用程序重新打開時,日誌/通知將停止。然而,問題是,當應用程序第二次進入後臺時,似乎原始後臺任務從未取消,並且創建了新的後臺任務,因此現在有兩個任務正在運行,每個檢查位置都在10秒間隔。如果應用程序被多次打開/發送到後臺,則會爲每個應用程序啓動後臺任務。
我想過設置一個標誌來說「應用程序已經被髮送到背景至少一次了?」,並且只在第一次發送到後臺時才運行該任務,但這似乎會導致其他問題,(作爲一個相對較新的iOS開發人員),我很好奇爲什麼後臺任務在應用程序進入前臺時未被取消。
的AppDelegate.h文件包含...
@interface AppDelegate : UIResponder <UIApplicationDelegate, CLLocationManagerDelegate> {
UIWindow *window;
UINavigationController *navigationController;
UIBackgroundTaskIdentifier bgTask;
BOOL inBackground;
}
的AppDelegate.m文件包含...
- (void)applicationDidEnterBackground:(UIApplication *)application {
inBackground = YES;
bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
while (inBackground == YES) {
NSLog(@"%@", @"Check location...");
[locationManager startUpdatingLocation];
[NSThread sleepForTimeInterval:10];
}
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
inBackground = NO;
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
更新是否按預期工作的位置,我只是不能工作爲什麼當應用程序進入前臺時後臺任務沒有被取消/結束。我想知道這與NSThread sleepForTimeInterval:
有什麼關係,但我不確定它是否是,或者如何解決(如果的確如此)。預先感謝您的幫助!
您應該將UIBackgroundMode添加到您的info.plist文件中,並將您的應用程序標識爲背景位置應用程序。 – J2theC
謝謝,J2theC,但是我們已經爲'所需的背景模式'設置了'位置更新的應用寄存器'。 (我會編輯問題以清楚地說明這一點)。位置更新應該是他們應該做的,只是這個永無止境的後臺任務就是問題所在。 – dvyio
我很確定你的實例變量'bgTask'在應用程序回到前臺時被重新分配,所以這個值不包含你想要殺死的標識符。考慮將這個標識符保存在'NSUserDefaults'中,或者更長一些。 – Hyperbole