2012-11-14 64 views
0

我正在開發一個跟蹤用戶在後臺位置的示例應用程序,但我不想離開位置服務始終啓用,但我的計時器中的某些內容不能正常工作。iOS不是典型的後臺位置跟蹤計時器問題

我的想法是,每x分鐘,服務就會繼續,當它有一個正確的新位置時,它會再次被釋放,現在設置爲10秒,僅用於測試。 (顯着LocationChange沒有伎倆,沒有足夠的囤積)

我正在尋找很多(iOS開發人員中心+ StackOverflow),並找到了「新的」後臺位置功能,它允許您在運行後10分鐘後運行代碼背景,使用beginBackgroundTaskWithExpirationHandler,幾個塊和一個計時器。

我設置背景模式,定位與現在我認爲我沒有需要處理的背景時(首先我想每15-20秒的位置)

代碼結束工作「好」,但:

  • 定時器有時會引發火災,有時不會。
  • 當計時器啓動時,至少需要10分鐘才能完成。
  • 在操作系統中的一些隨機動作(如進入搜索桌面)似乎估計定時器發生火災(不確定這一點,我不知道它是如何可能的,但它是...)

通過代碼將是另一個問題。

appdelegates的方法:

// applicationDidEnterBackground

- (void)applicationDidEnterBackground:(UIApplication *)application{ 

NSLog(@"to background"); 

UIApplication* app = [UIApplication sharedApplication]; 

bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ 
    [app endBackgroundTask:bgTask]; 
    bgTask = UIBackgroundTaskInvalid; 
}]; 

// Start the long-running task and return immediately. 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

    // Do the work associated with the task. 
    _triggertimer = nil; 
    [self initTimer]; 

}); 
NSLog(@"backgroundTimeRemaining: %.0f", [[UIApplication sharedApplication] backgroundTimeRemaining]);} 

// initTimer

- (void) initTimer{ 
NSLog(@"InitTimer "); 


UIApplication *app = [UIApplication sharedApplication]; 

bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ 



_triggertimer = [NSTimer scheduledTimerWithTimeInterval:10.0 
                target:self 
                selector:@selector(checkUpdates:) 
                userInfo:nil 
                repeats:YES]; 

[[NSRunLoop currentRunLoop] addTimer:_triggertimer forMode:NSDefaultRunLoopMode] ; 
[[NSRunLoop currentRunLoop] run]; 

}];} 

// checkUpdates

- (void)checkUpdates:(NSTimer *)timer{ 

NSLog(@"CheckUpdates "); 

UIApplication* app = [UIApplication sharedApplication]; 

if (nil == _locationManager) _locationManager = [[CLLocationManager alloc] init]; 

_locationManager.delegate = self; 


_locationManager.distanceFilter = 10; 
_locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; 

[_locationManager startUpdatingLocation]; 
[_locationManager startMonitoringSignificantLocationChanges]; 



double remaining = app.backgroundTimeRemaining; 
NSLog(@"Reminaing %f", remaining);} 

我嘗試了很多東西來試圖解決這個問題,也許我搞砸了或錯過了什麼......你看到了什麼?也許有些概念的錯誤,我想介紹自己的塊,我不域他們還¬¬

順便說一句,爲什麼所有我發現代碼中包含這與做任何事情beginBackgroundTaskWithExpirationHandler前?

bgTask = [app beginBackgroundTaskWithExpirationHandler:^{ 
    [app endBackgroundTask:bgTask]; 
    bgTask = UIBackgroundTaskInvalid; 
}]; 

我認爲這是爲了600秒的背景......但我不確定!

回答

0

好了,問題是,我打電話beginBackgroundTaskWithExpirationHandler兩次,一次在ApplicationDidEnterBackground,另一個裏面initTimer ...

0

當您的應用程序停止後臺時,定時器將不會再觸發,除非您擁有應用程序info.plist中設置的UIBackgroundModes key的「位置」值。

您可以使用beginBackgroundTaskWithExpirationHandler擴展允許您在後臺運行的時間(如果您尚未設置「位置」),但應該始終與相應的結束呼叫配對。

+0

我foget說出來,但我已經設置了UIBackgroundModes關鍵。 .. :( – meyo

+0

所以結束呼叫是 bgTask = [應用beginBackgroundTaskWithExpirationHandler:^ { [應用endBackgroundTask:bgTask]; bgTask = UIBackgroundTaskInvalid; }〕; 它應該是之前(如我在我的代碼)或調度後ch_async? – meyo