【備忘録】MapKitとCoreLocationで地図上に現在地を表示する方法


*初めての投稿です…もっとこうした方がいい、こういう書き方のほうがいい、ここは違う！等ありましたらご指導よろしくお願いします*。

XcodeはVersion 8.2.1
SwiftはVersion 3.0.2 です。



###まずは新しいプロジェクトを作るところから

 XcodeのCreate a New Xcode Project から Single View Applicationを選択します。

 Product Nameは **testMapApp**　(任意)　にとりあえずしておきます。
 Languageは **Swift**
 Devicesは **iPhone** 
 をそれぞれ選択します。
 
 下のチェックボックス3つは全て外したままでOK
 <br>
 
###次にMapKitとCoreLocationの2つのフレームワークを導入します
 
![framework_intro1.png](https://qiita-image-store.s3.amazonaws.com/0/148994/448c9812-f2d8-48c0-2ca4-42050a09294e.png "framework_intro1.png")

上の画像のように左の testMapApp を選択し、
TARGETS(Aみたいなマーク)のところの testMapApp を選択し、さらに右上の Build Phases を選択してください。
<br>
そうすると4つの▶で始まる項目が表示されるので、そのうちの Link Binary With Libraries のところの▶をクリックして展開してください。
その中の＋マークを押してください。
![framework_intro2.png](https://qiita-image-store.s3.amazonaws.com/0/148994/59482930-4528-957e-594f-ac823aa604ca.png "framework_intro2.png")

上の画像のように検索バーの中に　MapKit と入力して検索すると、
**MapKit.framework** という名前のフレームワークが表示されるので、それを選択してAdd!

同じ手順で **CoreLocation.framework** もAddしてください。

<br>
###次にストーリーボードにMapViewを配置して、配置したMapViewをコードと紐付けします

まずはMain.storyboard を選択します。
右下の検索バーに map と入力するとMapKitViewと出てくるので、それを Storyboard のViewController にドラッグアンドドロップします。
![MapView検索.png](https://qiita-image-store.s3.amazonaws.com/0/148994/dcde1bde-17d7-5900-3dbc-7b8e9d08fc85.png "MapView検索.png")

<br>

ドラッグアンドドロップしたMapViewが選択された状態で下に5つ並んでいるボタンの右から2番目を押して制約を追加します。
上下左右全て0でconstrain to margins のチェックを外してAdd 4 Constraintsをクリック。
![制約付.png](https://qiita-image-store.s3.amazonaws.com/0/148994/a7e7a3f5-e772-979a-5be9-3b2016e5776e.png "制約付.png")

<br>


その後、下に5つ並んでいるボタンの一番左のUpdateFramesをクリックするとViewControllerいっぱいにMapViewが広がると思います。
![UpdateFrame前.png](https://qiita-image-store.s3.amazonaws.com/0/148994/3ddf861b-6768-fce3-57f6-3c0c4753f877.png "UpdateFrame前.png")

<br>

次にコードのほうで ViewController.swift にMapKitとCoreLocationをimportします

```ViewController.swift

import UIKit
import Mapkit
import CoreLocation

class ViewController: UIViewController{
}
```
上のように追記しましょう。

もう一度 Main.storyboard を選択し、右上の○が２つ重なっているボタン![アシスタントエディタ.png](https://qiita-image-store.s3.amazonaws.com/0/148994/3c4922d6-e1aa-7135-4144-87e9525ec617.png "アシスタントエディタ.png")
を押してください。押すと、ストーリーボードの右側にコードの画面が出てくるはずです。



ViewController上のMapViewを選択します。controlキーを押しながらMapViewをコードの ViewControllerの中にドラッグアンドドロップしましょう。
![紐付け開始.png](https://qiita-image-store.s3.amazonaws.com/0/148994/2716ec46-0521-7814-6ae6-8bac7b8ab37b.png "紐付け開始.png")



すると次のような画面が出てくるので testMapView 
などロウワーキャメルケースで名前をつけましょう。
![紐付け中.png](https://qiita-image-store.s3.amazonaws.com/0/148994/a41a177d-0a02-5944-7697-a2537884db07.png "紐付け中.png")



次の画像のようになっていればOKです。
![紐付け完了.png](https://qiita-image-store.s3.amazonaws.com/0/148994/9f428da6-5c2b-d8f1-4d04-b342bc063007.png "紐付け完了.png")



ここまでできたらcommand+Rでシミュレーターを起動してみましょう。画面いっぱいに地図が表示されればOKです。
***

###位置情報の利用の許可のリクエストの実装と現在地の表示

#####現在地を取得、表示するためにユーザーに位置情報の利用の許可をリクエストする必要があります。
この機能を実装し、ユーザーに許可をもらえないと現在地の取得、表示はできません。

まずはXcodeの画面の一番左のファイルの階層などを表しているところの info.plist にカーソルを合わせ右クリック(副クリック)してください
OpenAs　▶SourceCode　を選択してください。

するとプロパティリストがソースコードで表示されます。
dict のタグで囲まれなかに key として NSLocationWhenInUseUsageDescriptionを、Stringには任意の文字列を以下のように入れます

```info.plist
<plist version="1.0">
<dict>

	//省略

	<key>NSLocationWhenInUseUsageDescription</key>
	<string>位置情報をこのアプリの起動時に使います</string>
</dict>
</plist>

```


<br>

次に ViewController.swift にも追記していきます。

```ViewController.swift
import UIKit
import MapKit
import CoreLocation

class ViewController: UIViewController, CLLocationManagerDelegate{

    @IBOutlet weak var testMapView: MKMapView!
    
    //CLLocationManagerの入れ物を用意
    var myLocationManager:CLLocationManager!
    
    
    
    override func viewDidLoad() {
        
        super.viewDidLoad()
        
        //CLLocationManagerをインスタンス化
        myLocationManager = CLLocationManager()
                
        
        //位置情報使用許可のリクエストを表示するメソッドの呼び出し
        myLocationManager.requestWhenInUseAuthorization()
        
    }
    
    //位置情報取得に失敗したときに呼び出されるメソッド
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("error")
    }
    
}
```
<br>

まずは `class ViewController:UIViewController` に続けて `CLLocationManagerDelegate` を追記します。
`CLLocationManagerDelegate` には許可のステータスが変更されたときに呼び出されるメソッドが定義されています。
このメソッドをViewController実装することで変更後の許可のステータスを受け取ることができます。
<br>
MapViewを紐付けしたところの下にCLLocationManagerの入れ物を定義します。
viewdidloadの中でCLLocationManagerをインスタンス化することでCLLocationManagerに含まれるメソッドを使えるようにします。
<br>

その次にCLLocationManagerのメソッドのひとつの`requestWhenInUseAuthorization()`を呼び出します。
この記述をすることでアプリ使用時の位置情報の利用の許可をユーザーにリクエストできます。
<br>

#####現在地の表示

下図のように画面左のMain.storyboardを選択→画面右側のShow the Attributes inspectorを選択→User Locationのチェックを入れればOK。
![userlocation.png](https://qiita-image-store.s3.amazonaws.com/0/148994/0c49aadd-525d-b8c0-8fe7-2e4067a604f1.png "userlocation.png")

あとはcommand+Rで起動して

![現在地取得.png](https://qiita-image-store.s3.amazonaws.com/0/148994/59be7df9-6eac-abd3-5325-8f4e8efe7f7a.png "現在地取得.png")


こんな感じになっていればOKです！