私が開発しているアプリケーションでこれを行いました。アプリがバックグラウンドにある場合、タイマーは機能しませんが、アプリは常に位置情報の更新を受信しています。ドキュメントのどこかで読んだことがあります(今は見つからないようです。更新を投稿します)。アプリがバックグラウンドにある場合、アクティブな実行ループでのみメソッドを呼び出すことができます。アプリデリゲートにはbgでもアクティブな実行ループがあるため、これを機能させるために独自のループを作成する必要はありません。[これが正しい説明であるかどうかはわかりませんが、私が読んだことからそれがどのように理解されたかです]
まず、アプリのinfo.plistにキー「BackgroundModes」の「location」オブジェクトを追加します。今、あなたがする必要があるのはあなたのアプリのどこでも位置の更新を開始することです:
CLLocationManager locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;//or whatever class you have for managing location
[locationManager startUpdatingLocation];
次に、アプリデリゲートで、場所の更新を処理するメソッド、たとえば-(void)didUpdateToLocation:(CLLocation *)locationを記述します。次に、ロケーションマネージャを開始したクラスにCLLocationManagerDelegateのメソッドlocationManager:didUpdateLocation:fromLocationを実装します(ロケーションマネージャデリゲートを「self」に設定したため)。このメソッド内では、位置の更新を処理する必要がある時間間隔が経過したかどうかを確認する必要があります。これを行うには、毎回現在の時刻を保存します。その時間が経過した場合は、アプリデリゲートからメソッドUpdateLocationを呼び出します。
NSDate *newLocationTimestamp = newLocation.timestamp;
NSDate *lastLocationUpdateTiemstamp;
int locationUpdateInterval = 300;//5 mins
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
if (userDefaults) {
lastLocationUpdateTiemstamp = [userDefaults objectForKey:kLastLocationUpdateTimestamp];
if (!([newLocationTimestamp timeIntervalSinceDate:lastLocationUpdateTiemstamp] < locationUpdateInterval)) {
//NSLog(@"New Location: %@", newLocation);
[(AppDelegate*)[UIApplication sharedApplication].delegate didUpdateToLocation:newLocation];
[userDefaults setObject:newLocationTimestamp forKey:kLastLocationUpdateTimestamp];
}
}
}
これにより、アプリがバックグラウンドにある場合でも、5分ごとにメソッドが呼び出されます。Imp:この実装はバッテリーを消耗します。位置データの精度が重要でない場合は、[locationManagerstartMonitoringSignificantLocationChanges]を使用する必要があります。
これをアプリに追加する前に、 http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/LocationAwarenessPG/Introduction/Introduction.htmlにあるLocationAwarenessプログラミングガイドをお読みください。