※本記事は、一般に公開されている情報を元に作成しています。
(WWDC 2014 発表資料より引用)
どういうこと?
iOS 8 から位置情報の取得の方法が変わるようです。今までの方法だと位置情報が取れなくなります。
objective c - Location Services not working in iOS 8 - Stack Overflow
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
になっている可能性があります。
現在の認証ステータスは次のデリゲートでチェックできます。
// CLLocationManager オブジェクトにデリゲートオブジェクトを設定すると初回に呼ばれる - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { if (status == kCLAuthorizationStatusNotDetermined) { // ユーザが位置情報の使用を許可していない } }
ユーザが位置情報の使用を許可していない場合は、次に説明する認証リクエストを使って位置情報の使用許可を要求します。
認証リクエスト
iOS 8 から CLLocationManager に次のメソッドが追加されています。
- requestAlwaysAuthorization - 位置情報の使用を常に許可してもらうよう要求
- requestWhenInUseAuthorization - 位置情報の使用をアプリ起動時のみ許可してもらうよう要求
※iOS 7環境でこのメソッドを呼ぶと当然クラッシュするので注意!
このメソッドを呼ぶことで、認証ダイアログが表示されます。ダイアログには最初に設定した「位置情報を使用する目的」も表示されます。
(WWDC 2014 発表資料より引用)
このメソッドは何度でも呼ぶことができますが、認証ダイアログが表示されるのは認証ステータスが kCLAuthorizationStatusNotDetermined
になっているときだけのようです。
ここで許可されることで、ようやく位置情報が取れるようになります。
対応しないとどうなるの?
AppStoreに上がっているアプリ(上記の対応をしてない)をダウンロードし、iOS 8で実行してみた場合の挙動を書こうと思ったのですが、NDAに抵触しそうなのでまた後日書きたいと思います。
2014/9/12追記:すでにAppStoreに並んでいるアプリをダウンロードし、iOS 8で実行した場合は、これまで通り位置情報を取得することができます。よって、昔リリースしたアプリがiOS 8対応してないので急に位置情報が取れなくなった!ということはありません。
参考になるリンク
- What’s New in Core Location - WWDC 2014 発表資料(PDF)
- objective c - Location Services not working in iOS 8 - Stack Overflow - Stackoverflowに寄せられた質問
- http://im-sei.tumblr.com/post/91824653043/ios-8 - Swiftのサンプルコード付きで詳しく解説されています