iOS
位置情報

iOS 8から位置情報を取得する方法が変わるよ

More than 3 years have passed since last update.

top.png

WWDC 2014 発表資料より引用)


つまりどういうこと?

iOS 8 から位置情報の取得方法が変わるようです。今までの方法だと位置情報が取れなくなります。(すでにAppStoreに並んでいるアプリについてはこの限りではありません)

iOS 8 : Location Services not working


My app that worked fine in iOS 7 doesn't work with the iOS 8 SDK.

CLLocationManager doesn't return a location, and I don't see my app under >Settings > Location Services either. I did a Google search on the issue but nothing >came up, what could be wrong?


▲Stack Overflowにもこの事に関する質問が寄せられていました


ポイント


  • 位置情報に対するプライバシーを、ユーザがより細かく設定できるようになりました(今までは許可する/しないの2択)


    • 使用中のみ許可 (WhenInUse)

    • 常に許可 (Always)

    • 許可しない (Never)



  • 位置情報の使用目的を記載するのが必須になった

  • 位置情報の認証リクエストするためのメソッドが増えた


何をすればよいのか

まずは Info.plist 内に位置情報を使用する目的を記載します。この項目は今まで任意でしたが、iOS 8からは必須になりました。



WWDC 2014 発表資料より引用)

キー名はプライバシーポリシーによって異なります。

使用中のみ許可
NSLocationWhenInUseUsageDescription

常に許可
NSLocationAlwaysUsageDescription


認証ステータスをチェック

認証ステータスも種類が増えてます。


  • kCLAuthorizationStatusNotDetermined

  • kCLAuthorizationStatusRestricted

  • kCLAuthorizationStatusDenied

  • kCLAuthorizationStatusAuthorized (deprecated)

  • kCLAuthorizationStatusAuthorizedAlways

  • kCLAuthorizationStatusAuthorizedWhenInUse

kCLAuthorizationStatusAuthorized非推奨になり、kCLAuthorizationStatusAuthorizedAlways(常に許可されている)、kCLAuthorizationStatusAuthorizedWhenInUse(使用中のみ許可されている)が増えています。

iOS 8で位置情報が取れない場合は、この認証ステータスが kCLAuthorizationStatusNotDetermined になっている可能性があります。

現在の認証ステータスは次のデリゲートでチェックできます。

Objective-C:

// CLLocationManager オブジェクトにデリゲートオブジェクトを設定すると初回に呼ばれる

- (void)locationManager:(CLLocationManager *)manager
didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
if (status == kCLAuthorizationStatusNotDetermined) {
// ユーザが位置情報の使用を許可していない
}
}

Swift:

func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {

switch status {
case .NotDetermined:
// ユーザが位置情報の使用を許可していない
}
}

ユーザが位置情報の使用を許可していない場合は、次に説明する認証リクエストを使って位置情報の使用許可を要求します。


認証リクエスト

iOS 8 から CLLocationManager に次のメソッドが追加されています。


  • requestAlwaysAuthorization - 位置情報の使用を常に許可してもらうよう要求

  • requestWhenInUseAuthorization - 位置情報の使用をアプリ起動時のみ許可してもらうよう要求

※iOS 7環境でこのメソッドを呼ぶと当然クラッシュするので注意!

このメソッドを呼ぶことで、認証ダイアログが表示されます。ダイアログには最初に設定した「位置情報を使用する目的」も表示されます。



WWDC 2014 発表資料より引用)

このメソッドは何度でも呼ぶことができますが、認証ダイアログが表示されるのは認証ステータスが kCLAuthorizationStatusNotDetermined になっているときだけのようです。

ここで許可されることで、ようやく位置情報が取れるようになります。


対応しないとどうなるの?

AppStoreに上がっているアプリ(上記の対応をしてない)をダウンロードし、iOS 8で実行してみた場合の挙動を書こうと思ったのですが、NDAに抵触しそうなのでまた後日書きたいと思います。

2014/9/12追記:すでにAppStoreに並んでいるアプリをダウンロードし、iOS 8で実行した場合は、これまで通り位置情報を取得することができます。よって、昔リリースしたアプリがiOS 8対応してないので急に位置情報が取れなくなった!ということはありません。


参考になるリンク


本記事は http://blog.koogawa.com/entry/2014/08/12/191215 でも公開しております。