#良くみかける説明
「iOSでCLLocationManager
を使う際に気を付ける事」等と言う記事をインターネットで良く見かけます。
大概はinfo.plist
にNSLocationAlwaysUsageDescription
とNSLocationWhenInUseUsageDescription
を追加して、CLLocationManager
を使いたいクラスにCLLocationManagerDelegate
を追加して、目的に応じて[locManager requestWhenInUseAuthorization];
か[locManager requestAlwaysAuthorization];
を呼び出して[locManager startUpdatingLocation];
を呼び出していますが、これで本当に大丈夫でしょうか?
#実はその前に調べる事が…
最も気を付けなくてはならないのは、この手前です。つまり、iOS端末の設定で位置情報サービスがそもそもオフになっていた場合です。この時は上記の手続きを行っても、そもそもサービス自体がオフになっていますのでCLAuthorizationStatus status = [CLLocationManager authorizationStatus];
は常にkCLAuthorizationStatusDenied
となります。
##位置情報サービスがONかOFFか調べよう
調べ方はとても簡単で
[CLLocationManager locationServicesEnabled];
を呼び出すだけです。結果はYES/NOで返却されます。NOだった場合は、位置情報サービスが使えないと言う事になりますが、アプリの補助機能として位置情報サービスを利用しているならともかく、位置情報がメインの場合はこれを放置していては困ります。
##位置情報サービスがOFFだったら、iOS端末の設定をしよう!
つまり[CLLocationManager locationServicesEnabled];
がNOだった場合は設定画面を開いて、位置情報サービスをONにしてもらう事が大事です。
前提条件として、CLLocationManagerDelegate
が@interface
のdelegateとして登録されている、とします。
- (void)locationManager:(CLLocationManager *)manager
didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
if(![CLLocationManager locationServicesEnabled])
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil
message:@"iOSの設定>プライバシー>位置情報サービスをONにしてください。"
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
[self openSettingLocation];
}]];
[self presentViewController:alert animated:YES completion:nil];
}
else
{
// もし、ステータスが未定だった場合は再設定を促す
if(status == kCLAuthorizationStatusNotDetermined)
{
[locManager requestWhenInUseAuthorization];
}
else
{
// 位置情報取得開始
// startUpdatingLocationを呼んだ時の日時をメンバ変数に保存
startUpdatingLocationAt = [NSDate date];
[locManager startUpdatingLocation];
}
}
}
このdelegateメソッドであるdidChangeAuthorizationStatus
は、CLLocationManager
オブジェクトにdelegateを設定した時と、CLLocationManager
の管理している認証状態が変化した時に呼び出されます。
ですから、設定を自分のアプリから開いて位置情報サービスをONに変えて「MyAppに戻る」をタップした場合は認証状態が変化したので呼び出されます。
しかし、OFFのまま戻られた場合はこのdelegateメソッドは呼び出されませんので、当該アプリで位置情報サービスを使う事ができないと言う事になります。