shobylogy

叩けシンプルの杖

CoreLocationを使ってバックグラウンドで位置情報を取得する

iOS 8からいろいろ変わってて、知ってた知識が使えなくなってたのでメモ。

概要

  • プロジェクト設定からBackgroundModes>Location updatesを有効にする
  • Info.plistに位置情報の使用目的を書く
  • CLLocationManagerを初期化
  • locationManagerのrequestAlwaysAuthorizationを呼ぶ
  • locationManagerのstartUpdatingLocationを呼ぶ
  • CLLocationManagerDelegateのlocationManager:didUpdateLocationsで変更を受け取る

プロジェクト設定からBackgroundModes>Location updatesを有効にする

プロジェクト設定から、BackgroundModesをON、Location updatesにチェックを入れる。

f:id:shoby:20150616020759p:plain

Info.plistに位置情報の使用目的を書く

位置情報の取得目的を書かないと使えなくなりました。

NSLocationAlwaysUsageDescriptionのキーを追加し、取得目的を書きます。 ここに書いた取得目的は、位置情報の利用を求めるアラートに表示されます。 f:id:shoby:20150616021110p:plain

CLLocationManagerを初期化

CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter = 40; // 30sec in walk
locationManager.activityType = CLActivityTypeFitness;

distanceFilterで何m移動ごとに情報を取得するか、activityTypeで移動手段は何かを設定する。 distanceFilterのdefaultはkCLDistanceFilterNone。変更があるとすべて通知される。 activityTypeは設定しなくても良いが、設定しておくと移動手段に合わせた位置情報取得のpauseをしてくれて、電源が節約できる。

locationManagerのrequestAlwaysAuthorizationを呼ぶ

if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
    [locationManager requestAlwaysAuthorization];
}

authorizationStatuskCLAuthorizationStatusNotDeterminedの時のみ、requestAlwaysAuthorizationを呼ぶ。 バックグラウンドでも常に位置情報を取得する許可を求める。

locationManagerのstartUpdatingLocationを呼ぶ

[locationManager startUpdatingLocation];

delegateに通知がくる。こない場合は何かミスをしているので、上記を確認。

  • CLLocationManagerDelegateのlocationManager:didUpdateLocationsで変更を受け取る 設定がうまくいっていたら、locationManager:didUpdateLocationsで変更を受け取れる。

緯度経度を使うにはこんな感じ。

CLLocation *location = locations.firstObject;
CLLocationDegrees latitude = location.coordinate.latitude;
CLLocationDegrees longitude = location.coordinate.longitude;

まとめ

CoreLocationを使うとバックグラウンドで位置情報を取得することができる。 プロジェクト設定やInfo.plist辺りは忘れやすいので気をつけよう。