Help us understand the problem. What is going on with this article?

【CoreLocation】位置情報を取得する

More than 1 year has passed since last update.

iOS10で位置情報を取得するには

ヘルス系のアプリでは現在位置情報、マップ系のアプリではどこかしらの位置情報を取得して周辺地図を表示したいことがあります。
現在位置を取得する方法・概要を記しておきます。(自分のために)
Swiftの基本的な文法や記述に関して、詳しく知りたい方は「10歳になったらプログラミングをはじめよう(iBooks Storeでみる)」を参考にしていただければと思います。
Xcodeの基本的な使い方に関しては「Hello, world. Swift3(iBooks Storeでみる)」を参考にしてください。

プロジェクトの概要

ビルド後、コンソールに位置情報(緯度:latitude, 経度:longitude)を出力する。
(Xcodeの機能を使って、シミュレータGPSが取得する位置データをシミュレートさせます)

動作環境

Xcode8.1
iOS10.1
Swift3.0.1

知っておくこと

CoreLocationフレームワーク

iOS SDKには位置情報関連の機能がパッケージされたCoreLocation フレームワークがあります。importするとCoreLocationの機能がファイル内で使えるようになります。
プロジェクトナビゲータのLinked Frameworks And Librariesに、CoreLocationを追加しておきましょう。

プライバシー情報の取得について

iOSアプリでは、ユーザの位置や連絡先、ヘルスなどプライバシーに関わる情報を取得する前に、ユーザから許可を得る必要があります。
許可を得るためには、Info.plistにその告知文を追加する必要があります。
Key: Location When In Use Usage Description
Value: 任意の文字列(「このアプリは位置情報を取得します」的な内容)

権限リクエストの種類

アプリがユーザから得られる認証にはいくつかの種類があります。

authorizedAlways

常に許可する。

authorizedWhenInUse

使用中だけ許可する。

denied

許可しない。

手順

大まかな流れは、以下のようになります。
1.フレームワークをインポート、マネージャ初期化
2.権限をリクエスト
3.マネージャの設定
4.プロトコルを採用して、デリゲートメソッドを実装

1. フレームワークのインポートとマネージャ初期化

CoreLocationフレームワークをインポートします。

ViewController.swift
import CoreLocation

位置情報の機能を管理する'CLLocationManager'クラスのインスタンスlocationManagerViewControllerクラスのメンバプロパティとして宣言しておきます。
locationManagerオブジェクトの初期化は、setupLocationManager()メソッドを定義して行なっています。

VeiwController.swift
class ViewController: UIViewController {

    var locationManager: CLLocationManager!

    override func viewDidLoad() {
        super.viewDidLoad()
        setupLocationManager()
    }

    func setupLocationManager() {
        locationManager = CLLocationManager()
    }
}

2. 権限をリクエスト

ユーザに対して、位置情報を取得する許可をリクエストします。
setupLocationManager()メソッド内で実装します。
今回は「アプリ使用中のみ許可を得る」ことにするので、インスタンスメソッドrequestWhenInUseAuthorization()を使います。
ただし、locationManagerオブジェクトが初期化に成功している場合のみ許可をリクエストします。

VeiwController.swift
class ViewController: UIViewController {

    var locationManager: CLLocationManager!

    override func viewDidLoad() {
        super.viewDidLoad()
        setupLocationManager()
    }

    func setupLocationManager() {
        locationManager = CLLocationManager()
        guard let locationManager = locationManager else { return }

        locationManager.requestWhenInUseAuthorization()
    }
}

3. マネージャの設定

ユーザから「アプリ使用中の位置情報取得」の許可が得られた場合のみ、マネージャの設定を行います。
管理マネージャが位置情報を更新するペースをdistanceFilterプロパティにメートル単位で設定します。
startUpdatingLocation()メソッドで、位置情報の取得を開始しています。

VeiwController.swift
class ViewController: UIViewController {

    var locationManager: CLLocationManager!

    override func viewDidLoad() {
        super.viewDidLoad()
        setupLocationManager()
    }

    func setupLocationManager() {
        locationManager = CLLocationManager()
        guard let locationManager = locationManager else { return }

        locationManager.requestWhenInUseAuthorization()

        let status = CLLocationManager.authorizationStatus()
        if status == .authorizedWhenInUse {
            locationManager.distanceFilter = 10
            locationManager.startUpdatingLocation()
        }
    }
}

4. プロトコル採用とデリゲートメソッド実装

ViewControllerクラスにCLLocationManagerDelegateプロトコルを採用します。
setupLocationManager()メソッド内で、許可ステータスが.authorizedWhenInUseの場合にViewControllerクラスが管理マネージャのデリゲート先になるようにします。

VeiwController.swift
class ViewController: UIViewController, CLLocationManagerDelegate {

    var locationManager: CLLocationManager!

    override func viewDidLoad() {
        super.viewDidLoad()    
        setupLocationManager()
    }

    func setupLocationManager() {
        locationManager = CLLocationManager()
        guard let locationManager = locationManager else { return }
        locationManager.requestWhenInUseAuthorization()

        let status = CLLocationManager.authorizationStatus()
        if status == .authorizedWhenInUse {
            locationManager.delegate = self
            locationManager.distanceFilter = 10
            locationManager.startUpdatingLocation()
        }
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let location = locations.first
        let latitude = location?.coordinate.latitude
        let longitude = location?.coordinate.longitude

        print("latitude: \(latitude!)\nlongitude: \(longitude!)")        
    }
}

locationManager(_: didUpdateLocations:)デリゲートメソッドは、位置情報を取得・更新するたびに呼ばれます。

ビルド

忘れずにInfo.plistに宣言文のKey:Valueセットを追加しておいてください。
また、プロジェクトナビゲータのLinked Frameworks And LibrariesCoreLocationを追加していないと、位置情報は取得できません。
スクリーンショット 2016-11-30 14.51.19.png
シミュレータで位置情報を取得するには、エディタエリア下部のボタンからシミュレートできます。
ロケーションを変更するたびに、コンソールに経度・緯度が出力されます。

chino_tweet
小学校で放課後プログラミング教室を実施しています。 学生や社会人向けも。 初学者のためのわかりやすい教材を目指しています。
https://www.facebook.com/ichihara.programming/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした