2014年初頭、AppleはiOS 7.0を7.1に更新し、アプリがバックグラウンドではなくフォアグラウンドでアクティブでない場合でも位置の更新を許可しました。それを行うにはどうすればよいですか?
AppleのiOS 7.1は位置情報のバグを修正します のような記事を読みました。ただし、Appleは、アプリが強制終了/終了/一時停止された場合でも、場所の更新を取得する方法に関するサンプルコードや通信に関連する情報を提供しませんでした。
iOS 7.1のリリースノート を読みました。私もそれに関連するものを見つけることができませんでした。
では、アプリが中断されている場合でも、iOS 7および8の位置情報の更新を実際に取得するにはどうすればよいでしょうか?
Core Locationフレームワークの実験による数か月の試行錯誤の後、アプリが強制終了または一時停止された場合でも位置の更新を取得するソリューションを見つけました。 iOS 7と8の両方でうまく機能します。
ソリューションは次のとおりです。
アプリが場所に基づいたモバイルアプリケーションであり、大幅な変更がある場合にデバイスの場所を監視する必要がある場合、iOSは、デバイスが最後の既知の場所から500メートル以上移動したときに位置座標を返します。はい、アプリがユーザーまたはiOS自体によって強制終了または一時停止された場合でも、現在地の更新を取得できます。
そのため、アプリが強制終了または一時停止されている場合でもlocationManager
が位置情報の更新を取得するには、startMonitoringSignificantLocationChanges
メソッドを使用する必要があり、startUpdatingLocation
は使用できません。
IOSが場所の更新をアプリに返したい場合、アプリを再起動して、キーUIApplicationLaunchOptionsLocationKey
をアプリのデリゲートメソッドdidFinishLaunchingWithOptions
に返すのに役立ちます。
キーUIApplicationLaunchOptionsLocationKey
は非常に重要であり、その処理方法を知っておく必要があります。キーを受け取ったら、新しいlocationManagerインスタンスを作成する必要があり、locationManagerデリゲートメソッドdidUpdateLocations
で位置の更新を取得します。
サンプルコードは次のとおりです。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
self.shareModel = [LocationShareModel sharedModel];
if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) {
self.shareModel.anotherLocationManager = [[CLLocationManager alloc]init];
self.shareModel.anotherLocationManager.delegate = self;
self.shareModel.anotherLocationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
self.shareModel.anotherLocationManager.activityType = CLActivityTypeOtherNavigation;
if(IS_OS_8_OR_LATER) {
[self.shareModel.anotherLocationManager requestAlwaysAuthorization];
}
[self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];
}
return YES;
}
didFinishLaunchingWithOptions
メソッドに加えて、アプリがアクティブなときにlocationManager
インスタンスを作成しました。以下にコード例を示します。
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[self.shareModel.anotherLocationManager stopMonitoringSignificantLocationChanges];
if(IS_OS_8_OR_LATER) {
[self.shareModel.anotherLocationManager requestAlwaysAuthorization];
}
[self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
if(self.shareModel.anotherLocationManager)
[self.shareModel.anotherLocationManager stopMonitoringSignificantLocationChanges];
self.shareModel.anotherLocationManager = [[CLLocationManager alloc]init];
self.shareModel.anotherLocationManager.delegate = self;
self.shareModel.anotherLocationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
self.shareModel.anotherLocationManager.activityType = CLActivityTypeOtherNavigation;
if(IS_OS_8_OR_LATER) {
[self.shareModel.anotherLocationManager requestAlwaysAuthorization];
}
[self.shareModel.anotherLocationManager startMonitoringSignificantLocationChanges];
}
アプリが強制終了または一時停止されている場合でも、iOS 7および8の場所の更新を取得する方法の詳細を説明する記事を書きました。また、このソリューションをテストする方法の手順を含む完全なソースコードをGitHubにアップロードしました。
詳細については、次のURLをご覧ください。
locationManager = [[CLLocationManager alloc] init];
#define IS_OS_8_OR_LATER ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
if(IS_OS_8_OR_LATER)
{
[locationManager requestWhenInUseAuthorization];
}
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; //whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
[locationManager startUpdatingLocation];
このコードは、バックグラウンド実行ではなく、実行中のフォアグラウンドアプリのみを更新します
[locationManager requestWhenInUseAuthorization];