[はじめてのiOSアプリ]xcodeで地図アプリを作成（その３）

# はじめに

iOSアプリを作ってみたいけど
何から始めて良いのかわからない

とりあえず、
「やってみました」記事を参考に
地図アプリを真似てみようと思う

という記事の３回目です。

今回は、位置情報を取得します。

# 位置情報の取得
1. CoreLocationをインポート
   - 画面左側のファイルツリーから[ViewController.swift]を選択し、画面中央に表示されるエディタで、以下のように修正
   - 【なぜ？】
     - 位置情報ライブラリ(CoreLocation)を使うことを宣言することで、位置情報取得のプログラムを記述できるようになる

    ```swift:ViewController.swift
    import UIKit
    import CoreLocation  // この行を追加
    
    class ViewController: UIViewController {
    ```
1. CoreLocation 用の変数を追加
   - エディタで、以下のように修正
   - 【なぜ？】
     - この変数を通してプログラムで位置情報を取り扱うため
   
    ```swift:ViewController.swift
    class ViewController: UIViewController {
        var locationManager: CLLocationManager!  // この行を追加
    
        override func viewDidLoad() {
    ```
1. CoreLocation の delegate の使用を宣言（プロトコルの継承）
   - エディタで、以下のように修正
   - 【なぜ？】
     - プロトコルを継承することで、位置情報更新などのイベントに対する処理をプログラムすることができるようになる
     - 今回は ViewController.swift で継承したことで、クラスが増えずシンプルな実装とすることができた
     - （今回はしないが）別クラスで継承・実装すれば再利用性の高いクラスとできると思う

    ```swift:ViewController.swift
    class ViewController: UIViewController, CLLocationManagerDelegate {  //この行を修正
        var locationManager: CLLocationManager!
    
        override func viewDidLoad() {
    ```
1. CoreLocation 変数の初期化とCoreLocationの初期処理
   - エディタで、以下のように修正
   - 【なぜ？】
     - 変数は、初期化しないと使えない
     - 位置情報更新時のイベントを処理するプログラムを指定する必要がある
     - 明示的に位置情報取得開始を指示する必要がある
     - 利用者から、このアプリで位置情報を使う許可をもらう必要がある

    ```swift:ViewController.swift
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    
        // この行↓から
        locationManager = CLLocationManager()  // 変数を初期化
        locationManager.delegate = self  // delegateとしてself(自インスタンス)を設定
    
        locationManager.startUpdatingLocation()  // 位置情報更新を指示
        locationManager.requestWhenInUseAuthorization()  // 位置情報取得の許可を得る
        // この行↑までを追加
    }
    ```
1. 位置情報更新時に呼び出される処理を記述
   - エディタで、以下のように修正
   - 【なぜ？】
     - 位置情報更新時に呼び出される処理
     - 最新(last)の位置情報から緯度経度を取り出している
     - 地図と連携する場合は、最新の位置を用いて地図を更新すればよいはず

    ```swift:ViewController.swift
    override func viewDidLoad() {
        // 表示の都合上、プログラムを省略しています
    }
    
    // この行↓から
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations:[CLLocation]) {
        let longitude = (locations.last?.coordinate.longitude.description)!
        let latitude = (locations.last?.coordinate.latitude.description)!
        print("[DBG]longitude : " + longitude)
        print("[DBG]latitude : " + latitude)
    }
    // この行↑までを追加
    ```
1. 位置情報使用許可文字列を設定
   - 画面左側のファイルツリーから[MyGpsMap]-[Info.plist]を選択
   - Ctrl+クリックでコンテキストメニューを表示し[Open As]-[Source Code]を選択（↓のようにテキストエディタ形式で表示される）
     - 【なぜ？】
         - セキュリティ上の理由により、利用許可を得る必要がある<br>
<img width="1316" alt="InfoList-edit.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521802/c50f1122-549f-004e-569d-334a4ea5c244.png">
   - ファイルの後ろ付近に以下の行を追加
     - 【なぜ？】
         - 利用許可画面に表示される文字列
         - この文字列設定が存在しないと、利用許可を完了できず位置情報が取得できない

    ```Info.plist
        </array>
        <!-- ここ↓から追加 -->
        <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
        <string>常に位置情報の利用を許可する理由/目的を書く</string>
        <key>NSLocationWhenInUseUsageDescription</key>
        <string>アプリ起動時に位置情報の利用を許可する理由/目的を書く</string>
        <!-- ここ↑まで追加 -->
    </dict>
    </plist>
    ```
1. テスト実行
   - Xcode 左上の矢印アイコンをクリック
   - 位置情報利用確認画面が表示される<br>
<img width="535" alt="AllowLocationAccess.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521802/7caabc3d-4762-05ec-3cb3-db0c319910e6.png">
   - Simulator のメニューから[Debug]-[Location]-[City Run]を選択することでGPSが更新される<br>
<img width="1316" alt="UpdateLocation.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521802/0a99dd9f-86f6-3c5b-99ac-f95253a40681.png">

# 今回の到達点
- 位置情報(GPS)が取得できるようになった

# 参考情報

```ViewController.swift
//
//  ViewController.swift
//  MyGpsMap
//
//  Created by shinobee on 2019/11/24.
//  Copyright © 2019 shinobee. All rights reserved.
//

import UIKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate {
    var locationManager: CLLocationManager!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        locationManager = CLLocationManager()
        locationManager.delegate = self

        locationManager.startUpdatingLocation()
        locationManager.requestWhenInUseAuthorization()
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations:[CLLocation]) {
        let longitude = (locations.last?.coordinate.longitude.description)!
        let latitude = (locations.last?.coordinate.latitude.description)!
        print("[DBG]longitude : " + longitude)
        print("[DBG]latitude : " + latitude)
    }
}
```

# 連載
1. [[はじめてのiOSアプリ]xcodeで地図アプリを作成（その１：プロジェクト作成）](https://qiita.com/shinobee/items/1f6d26451336bf736484)
1. [[はじめてのiOSアプリ]xcodeで地図アプリを作成（その２：地図表示）](https://qiita.com/items/50e1acee3024c3e26fb9)
1. [[はじめてのiOSアプリ]xcodeで地図アプリを作成（その３：位置情報取得）](https://qiita.com/items/b8d287d2e34af20aab64)
1. [[はじめてのiOSアプリ]xcodeで地図アプリを作成（その４：位置情報と連携した地図表示）](https://qiita.com/items/a91c49ebf5301d936120)
1. [[はじめてのiOSアプリ]xcodeで地図アプリを作成（その５：アプリアイコン設定）](https://qiita.com/items/24804294ab86635ee5d3)
1. [[はじめてのiOSアプリ]xcodeで地図アプリを作成（その６：拡大・縮小ボタン追加）](https://qiita.com/items/12c54c4e253bc48cad4d)
1. [[はじめてのiOSアプリ]xcodeで地図アプリを作成（その７：地図を拡大・縮小）](https://qiita.com/items/4406c4fdf2fbdcc40533)
1. [[はじめてのiOSアプリ]xcodeで地図アプリを作成（その８：地名表示）](https://qiita.com/items/3363779d0ea11ca6073c)
1. [[はじめてのiOSアプリ]xcodeで地図アプリを作成（その９：ソースコード管理）](https://qiita.com/items/d0e63020b0dce4c70542)

<!-- eof -->