Swiftで現在位置の取得と地図にピンを立てる

# 概要
Swiftで現在位置の取得と地図にピンを立てる方法です。

　1. Info.pistに位置情報へのアクセス許可を追加(NSLocationWhenInUseUsageDescription)
　2. MKMapViewを全面に貼りstartUpdatingLocation()で位置情報の取得を開始
　3. CLGeocoderで住所から緯度経度を取得してaddAnnotation()でピンを立てる

他の記事も探しましたが、すぐに使えるコードがなかったのでシェアしておきます。

# 環境
Swift 4
Xcode 10.1

# 結果
<img width="375" alt="IMG_2432.png" src="https://qiita-image-store.s3.amazonaws.com/0/117784/7df6446f-ca6c-91cf-4e19-cbf0a770f211.png">
<img width="375" alt="IMG_2433.png" src="https://qiita-image-store.s3.amazonaws.com/0/117784/61b874be-d1fc-e026-0e27-6b0c3b7ac862.png">

# コード
```
import UIKit
import MapKit
import CoreLocation

struct Annotation {
    let address: String
    let title: String?
    let subtitle: String?
}

class MapViewController: UIViewController {
    
    @IBOutlet weak var mapView: MKMapView!
    
    let locationManager = CLLocationManager()
    
    override func viewDidLoad() {
        super.viewDidLoad()

        configureSubviews()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        startUpdatingLocation()
        
        let annotation = Annotation(
            address: "神奈川県横浜市青葉区青葉台1-7-3",
            title: "青葉台駅です",
            subtitle: "田園都市線はいつも激混み")
        add(with: annotation)
    }
    
    private func add(with annotation: Annotation) {
        CLGeocoder().geocodeAddressString(annotation.address) { [weak self] (placeMarks, error) in
            guard let placeMark = placeMarks?.first,
                let latitude = placeMark.location?.coordinate.latitude,
                let longitude = placeMark.location?.coordinate.longitude else { return }
            
            let point = MKPointAnnotation()
            point.coordinate = CLLocationCoordinate2DMake(latitude, longitude)
            point.title = annotation.title
            point.subtitle = annotation.subtitle
            self?.mapView.addAnnotation(point)
        }
    }
    
    private func startUpdatingLocation() {
        switch CLLocationManager.authorizationStatus() {
        case .notDetermined:
            locationManager.requestWhenInUseAuthorization()
        default:
            break
        }
        locationManager.startUpdatingLocation()
    }
    
    private func configureSubviews() {
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.distanceFilter = 100
        locationManager.startUpdatingLocation()
        
        mapView.delegate = self
        mapView.mapType = .standard
        mapView.userTrackingMode = .follow
        mapView.userTrackingMode = .followWithHeading
    }
}


// MARK: - MKMapViewDelegate
extension MapViewController: MKMapViewDelegate {
}


// MARK: - CLLocationManagerDelegate
extension MapViewController: CLLocationManagerDelegate {
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        print("位置情報の取得に成功しました")
    }
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        let alert = UIAlertController(title: nil, message: "位置情報の取得に失敗しました", preferredStyle: .alert)
        alert.addAction(UIAlertAction.init(title: "OK", style: .default, handler: { (_) in
            self.dismiss(animated: true, completion: nil)
        }))
        present(alert, animated: true, completion: nil)
    }
}
```