私たちが知っているように、バックグラウンド モードで実行されているアプリケーションにはいくつかの制限があります。たとえば、NSTimer は機能しません。バックグラウンドモードで動作するこのような「タイマー」を書いてみました。
-(UIBackgroundTaskIdentifier)startTimerWithInterval:(NSTimeInterval)interval run:(void (^)())runBlock complete:(void (^)())completeBlock
{
NSTimeInterval delay_in_seconds = interval;
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, delay_in_seconds * NSEC_PER_SEC);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// ensure the app stays awake long enough to complete the task when switching apps
UIBackgroundTaskIdentifier taskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
completeBlock();
}];
NSLog(@"remain task time = %f,taskId = %d",[UIApplication sharedApplication].backgroundTimeRemaining,taskIdentifier);
dispatch_after(delay, queue, ^{
// perform your background tasks here. It's a block, so variables available in the calling method can be referenced here.
runBlock();
// now dispatch a new block on the main thread, to update our UI
dispatch_async(dispatch_get_main_queue(), ^{
completeBlock();
[[UIApplication sharedApplication] endBackgroundTask:taskIdentifier];
});
});
return taskIdentifier;
}
この関数を次のように呼び出しました。
-(void)fire
{
self.taskIdentifier = [self startTimerWithInterval:10
run:^{
NSLog(@"timer!");
[self fire];
}
complete:^{
NSLog(@"Finished");
}];
}
このタイマーは完璧に機能しますが、1 つ問題があります。バックグラウンド タスクの最長時間は 10 分です (startTimerWithInterval の NSLog を参照してください)。
タイマーを 10 分以上動作させる方法はありますか? ところで、私のアプリケーションは BLE アプリケーションです。既に UIBackgroundModes を bluetooth-central に設定しています。