LoginSignup
68
74

More than 5 years have passed since last update.

iOS9 Core Locationの使いかた(iOS8から変わった点を中心に)

Posted at

Location Service(位置情報サービス)は、iOS9から、「常に許可」、「このAppの使用中のみ許可」の2モードになり、バッテリーの減りを抑える工夫がこらされました。それにともない、CoreLocationのCLLocationManagerの実装のしかたに変更があります。新しい実装のしかたについて、かんたんにまとめてみました。

位置情報サービスを常に許可する

アプリケーションがバックグラウンドにまわっても位置情報サービスを使い続けるモードです。
XcodeプロジェクトのCapabilitiesを開き、
always01.png
Background ModesをONにし、Location updatesにチェックを入れます。次に同じくプロジェクトのInfoを開き、
always02.png
新規キーを追加します。キー値はNSLocationAlwaysUsageDescriptionとし、値(Value)は、任意の文字列を入力します。この任意の文字列は、後で説明します。
これでプロジェクトの設定ができました。次にプログラムコードの説明をします。ViewControllerに二つのラベルを置き、ボタンを押したら経度、緯度を表示するプログラムにします。

ViewController.swift
import UIKit
import CoreLocation // フレームワークのインポート
// Delegateプロトコルの追加
class ViewController: UIViewController, CLLocationManagerDelegate {

    @IBOutlet weak var latitudeLabel: UILabel!
    @IBOutlet weak var longitudeLabel: UILabel!

    var locationManager: CLLocationManager?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Location Managerの生成、初期化
        locationManager = CLLocationManager()
        locationManager?.distanceFilter = 500 // 500m移動したら通知する。
        locationManager?.delegate = self
        if CLLocationManager.authorizationStatus() != CLAuthorizationStatus.AuthorizedAlways { // 注1
            locationManager?.requestAlwaysAuthorization()
            // 位置情報サービスを開始するか、ユーザに尋ねるダイアログを表示する。
        }
    }

    @IBAction func getLocation(sender: AnyObject) {
        // 位置情報更新を開始。
        locationManager?.startUpdatingLocation()
    }
    // Delegateメソッド
    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let cordinate = locations[0].coordinate
        latitudeLabel.text = "\(ordinate.latitude)" // 緯度表示。
        longitudeLabel.text = "\(ordinate.longitude)" // 経度表示。
    }

}

注1 この条件式は、位置情報サービスが「常に許可」になっていなければ、ダイアログを出す」という、ちょっと乱暴な条件です。「アプリが使用中許可」になっていたり、ユーザが使用を止めていたら、ダイアログを出すのは考えようという配慮が必要かもしれません。

アプリを起動すると、最初に下のダイアログが表示されます。
always03.png
このダイアログは、Allowを選択すると、アプリのインストール直後、一度だけ表示されます。プロジェクトのInfoで入力した(任意の)文字列は、このダイアログの中のコメントになります。

このAppの使用中のみ許可

位置情報サービスをバックグラウンドで動かす必要がないので、Background Modesの設定はしません。
プロジェクトのInfoで、
inuse01.png
新規キーを追加し、NSLocationWhenInUseUsageDescriptionとします。値は任意の文字列を入力します。
プログラムコードは、「常に表示」とおおむね同じですが、iOS9より、「位置情報を一度だけ取得」という新しいメソッドが追加されたので、それを使ってみます。

ViewController.swift
import UIKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {

    @IBOutlet weak var latitudeLabel: UILabel!
    @IBOutlet weak var longitudeLabel: UILabel!

    var locationManager: CLLocationManager?

    override func viewDidLoad() {
        super.viewDidLoad()

        locationManager = CLLocationManager()
        locationManager?.distanceFilter = 500
        // 「アプリ使用時のみ許可」でなかったら、ダイアログを出す。
        if CLLocationManager.authorizationStatus() != CLAuthorizationStatus.AuthorizedWhenInUse {
            locationManager?.requestWhenInUseAuthorization()
        }
        locationManager?.delegate = self
    }

    @IBAction func getLocation(sender: UIButton) {
        // 位置情報を一度だけ取得。
        locationManager?.requestLocation()
    }

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        if let location = locations.last {
            latitudeLabel.text = "\(location.coordinate.latitude)"
            longitudeLabel.text = "\(location.coordinate.longitude)"
        } else {
            print("Could't get any location services.")
        }
    }
    // 位置情報を一度だけ取得する場合、取得に失敗した時のDelegateメソッドの実装が必要。
    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
        print("Failure")
    }

}

アプリ起動すると、最初に下のダイアログが出ます。
inuse03.png
最後に、位置情報サービスの実装が成功すると、iOSのSetting>Privacy>Location Serviceに、開発中のアプリが追加されています。確認してください。
inuse02.png

68
74
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
68
74