koogawa blog

iOS、Android、foursquareに関する話題

【iOS 9対応:Core Location】知っておきたい位置情報周りの変更点

※本記事は、一般に公開されている情報を元に作成しています。記事中の画像はWWDCのスライドのものを引用させて頂いております

位置情報を扱うiOSアプリを開発する際に必要となる Core Location ですが、iOS 9でもいくつか変更点があるようです。以下に変更点をまとめます。

Background Location

iOS 8までは「Capabilities > Background Modes > Location updates」にチェックを入れておくだけでバックグラウンドでも継続的に位置情報を取得することができました。

スクリーンショット 2015-07-01 18.48.49.png

iOS 9からは CLLocationManager

var allowsBackgroundLocationUpdates: Bool

というプロパティが追加され、これを YES にしないとバックグラウンドで位置情報を取得できないようです。

注意しないといけないのが、このプロパティはデフォルトで NO だということです。iOS 9以上で、かつバックグラウンドでの位置情報取得が必要な場合は、このプロパティを YES にする必要がありそうです。

let locationManager = CLLocationManager()
if #available(iOS 9.0, *) {
    locationManager.allowsBackgroundLocationUpdates = true
}

Single location

iOS 8までは、startUpdatingLocation メソッドを用いて継続的に位置情報を取得し続けることができました。一方、一回だけ位置情報を取得したい場合には、フラグなどを用意して自前で処理を実装する必要がありました。

iOS 9からは

func requestLocation()

というメソッドが追加になっており、一度きりの位置情報取得が可能になりました。

このメソッドを実行すると、指定された測位精度(desiredAccuracy)に基づき測定を行い、位置情報が取得できた際には

-locationManager:didUpdateLocations:

が呼ばれ、取得できなかった場合は

-locationManager:didFailWithError:

が呼ばれます。

Authorization

ユーザーに位置情報の使用許可を求める際、

-requestWhenInUseAuthorization
-requestAlwaysAuthorization

のメソッドを使う点はiOS 8から変わっていません。

(参考)blog.koogawa.com

iPhone側で許可を求める際のフローもこれまでと変わっていません。

一方、Apple Watchにおいては、Watch Extensionが実機側に移動したこともあり、この辺の挙動が変わっています。

それぞれ詳しく見て行きましょう。

iPhone側で許可する場合

スクリーンショット 2015-07-02 15.45.17.png

これまで通り、iPhone上に許可を求めるアラートが表示されます。Apple Watch上には何も表示されません。

Apple Watch上で許可する場合

スクリーンショット 2015-07-02 15.33.29.png

iPhoneアプリ側で位置情報の使用を許可するよりも先にWatchアプリ側で位置情報を使おうとした場合がこのパターンです。フローは次の通りです。

  1. Apple Watch上に「iPhone側で位置情報の使用を許可するよう求めるアラート」が表示される(dismissボタンで閉じれる)
  2. iPhone上に許可を求めるアラートが表示される
  3. iPhone上で許可するとApple Watchでも位置情報が取得できるようになる

このようなフローになっているのは、ユーザにApple Watch上で位置情報の使用を許可させるのはあまり良いUXではない、ことなどが理由のようです。詳しくはWWDCのビデオを参照してください。

What's New in Core Location - WWDC15 - Videos - Apple Developer

Apple Watch: Best practice

watchOS 1までは、位置情報を取得する際に

-startUpdatingLocation

メソッドが使用できました。

しかし、watchOS 2からはこのメソッドが使えなくなっています(deprecatedではなく使用不可)。

代わりに、先ほど紹介した requestLocation メソッドを使うようです。つまり、基本的にwatchOS 2では継続的な位置情報の取得ができません。

どうしても継続的に位置情報を取りたい場合は Watch Connectivity を使ってね、ということらしいです。Watch Connectivityについては、次のビデオを参照してください。

また、私のブログでも詳しく解説しています。

ここでは、Watch Connectivityを用いて継続的に位置情報を取得する際に使用するメソッド名のみ載せておきます。

Watch -> iPhone

-sendMessage:replyHandler:errorHandler:

iPhone -> Watch

-updateApplicationContext:
-allowDeferredLocationUpdatesUntilTraveled:timeout:

参考になるリンク