見出し画像

[Swift5] RealmとMkMapViewを使ってピンの位置を登録

いま、MkMapViewを使った地図アプリを作っています!
概要としては、地図上でピンを打った場所にタグ付けし、お気に入りの場所をタグで管理できるアプリにしようと思っています🗺

アプリを作る途中で学んだことをちょこちょこ書いていこうと思います😊

今回は、Realmを使って、
・マップ上で長押しタップされた時にピンを保存する
です!

Realm Databaseを使えるようにするまではこの記事を参考にしました↓

RealmはCocoa Podsで追加するので、もしCocoa Podsがまだ入ってない方はこの記事が参考になります↓

もし、「No such module 'RealmSwift'」がでている場合は、拡張子が".xcodeproj"のプロジェクトファイルを開いている可能性があります。
".xcworkspace"のプロジェクトファイルを開き直しましょう😉


地図上の長押しでピンを追加

まずは長押しタップでピンを追加する処理を作ります。

1. MKMapViewを配置

Main.storyboardに「MKMapView」を全面に配置しておきます。

スクリーンショット 2020-06-18 19.00.46

配置したStoryboard上のMKMapViewと、ViewControllerをIBOutletで紐づけます。

そしてmapViewのdelegateも設定しておきます。

class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {

    @IBOutlet weak var mapView: MKMapView!

    override func viewDidLoad() {
       super.viewDidLoad()
       
       mapView.delegate = self
       
   }
}


2. MKMapViewに長押しのジェスチャーをつける

長押しの検知は「UILongPressGestureRecognizer」を追加することで実現できます👏

Storyboard上で「Long Press Gesture Recognizer」をMKMapViewに追加します。

スクリーンショット 2020-06-19 8.58.38

そして、@IBActionでViewControllerと紐づけます。

@IBAction func longPressMap(_ sender: UILongPressGestureRecognizer) {

}

紐付けできたら、ピンを表示する処理を書いていきます。

// ピンのオブジェクト
var pin: MKPointAnnotation!

@IBAction func longPressMap(_ sender: UILongPressGestureRecognizer) {
    // ロングタップの最初の感知のみ受け取る
    if(sender.state != UIGestureRecognizer.State.began){
        return
    }
    pin = MKPointAnnotation()

    // ロングタップした位置情報を取得
    let location:CGPoint = sender.location(in: mapView)

    // 取得した位置情報をCLLocationCoordinate2D(座標)に変換
    let coordinate:CLLocationCoordinate2D = mapView.convert(location, toCoordinateFrom: mapView)

    // 座標をピンに設定
    pin.coordinate = coordinate

    // ピンを追加
    mapView.addAnnotation(pin)

}

ピンの追加はこの記事を参考にさせていただきました↓


追加したピンの座標をRealm Databaseに保存する

保存したピンは、次回アプリを開いた時に表示できるようにしたいですよね?
そのために、追加したピンの緯度と経度を保存しておきます。

ピンが打たれた場所の緯度と経度を取得するには以下のようにします。

let center = mapView.convert(location, toCoordinateFrom: mapView)
// 緯度
let lat:String = center.latitude.description
// 経度
let lon:String = center.longitude.description

次に、この座標をRealm Databaseに保存します。

保存するために、まずはModelをつくります。

import RealmSwift

class Pin: Object {
   
   // 緯度
   @objc dynamic var latitude = ""
   
   // 経度
   @objc dynamic var longitude = ""

}

保存処理の関数を用意します。
この処理を書くクラスには”import RealmSwift”を追加する必要があります。
保存処理を外だしするときはそのクラスに、ViewControllerにそのまま書いちゃう場合はViewControllerに追加してください。

func savePin(latitude: String, longitude: String) {
    let pin = Pin()
    pin.latitude = latitude
    pin.longitude = longitude

    let realm = try! Realm()
    try! realm.write {
        realm.add(pin)
    }
}

そして、ViewControllerに作った長押し処理の関数"longPressMap"からこの保存処理を呼び出します。

savePin(latitude: lat, longitude: lon)


これで完成です!

次は保存したピンを表示するnoteを書こうと思います😊

この記事が気に入ったらサポートをしてみませんか?