ニフクラ mobile backend(mBaaS)お役立ちブログ

スマホアプリ開発にニフクラ mobile backend(mBaaS)。アプリ開発に役立つ情報をおとどけ!

Swiftのデータストアの位置情報をMapKitに描画する

f:id:mbaasdevrel:20181006142604p:plain

mBaaSのデータストアでは位置情報を扱えます。位置情報なので、地図アプリや現実世界に合わせた情報を紹介するアプリなどに向いています。今回はデータストアに保存した位置情報を取得してiOSのMapKitに表示する方法を解説します。

iOS SDKを導入する

イントロダクション (iOS) : クイックスタート | ニフクラ mobile backendを参考にiOS SDKを導入します。今回はCocoaPods版を導入しています。

MapKitを有効にする

XcodeのCapabilitiesタブでMapを有効にします。

f:id:mbaasdevrel:20181006142457p:plain

info.plistを更新する

位置情報を扱うのでinfo.plistに項目を追加します。追加するのは以下の二つです。

  • Privacy - Location When In Use Usage Description
  • Privacy - Location Always and When In Use Usage Description

f:id:mbaasdevrel:20181006142435p:plain

mBaaSを初期化する

アプリ起動時にNCMBを初期化します。今回はcocoapods-keysも使っています。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
  // Override point for customization after application launch.
  let keys = NcmbLocationKeys()
  NCMB.setApplicationKey(keys.applicationKey, clientKey: keys.clientKey)
  return true
}

Main.storyboardにMapViewなどを追加する

今回は以下のコンポーネントを追加しています。これらはViewController.swiftにアウトレットで接続しています。

  • MapView : MapView
  • Label : latitude
  • Label : longitude
  • Button : Start
  • Button : Stop

f:id:mbaasdevrel:20181006142514p:plain

ViewControler.swiftにデリゲート追加

MapKitを扱うためのデリゲートを追加します。

import MapKit

class ViewController: UIViewController, CLLocationManagerDelegate {
  @IBOutlet weak var mapView: MKMapView!
    @IBOutlet weak var latLabel: UILabel!
    @IBOutlet weak var lngLabel: UILabel!
  
  var locationManager : CLLocationManager?

  func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        switch status {
        case .notDetermined:
            manager.requestWhenInUseAuthorization()
        case .restricted, .denied:
            break
        case .authorizedAlways, .authorizedWhenInUse:
            break
        }
    }

startボタンをタップしたタイミングで位置情報を取得開始

今回は自動ではなく、startボタンをタップした時にはじめて位置情報を取得します。

@IBAction func tapStartButton(_ sender: UIButton) {
  if locationManager != nil { return }
  locationManager = CLLocationManager()
  locationManager!.delegate = self
  locationManager!.requestWhenInUseAuthorization()
  if CLLocationManager.locationServicesEnabled() {
    locationManager!.startUpdatingLocation()
  }
  // tracking user location
  mapView.userTrackingMode = MKUserTrackingMode.followWithHeading
  mapView.showsUserLocation = true
  mapView.removeAnnotations(mapView.annotations)

データストアを検索し、結果をそのままmapViewに追加します。

  let query = NCMBQuery(className: "Station")
  query?.findObjectsInBackground({(objects, err) in
    if err != nil {
    } else {
      let stations = objects as! [NCMBObject]
      var annotations: [MKPointAnnotation] = []
      for station in stations {
        let geo = station.object(forKey: "geo") as! NCMBGeoPoint
        let location = CLLocation.init(latitude: geo.latitude, longitude: geo.longitude)
        let annotation = MKPointAnnotation()
        annotation.coordinate = location.coordinate
        annotations.append(annotation)
      }
      self.mapView.addAnnotations(annotations)
    }
  })
}

実行する

今回は山の手線の駅を位置情報として登録しています。これらを表示すると、下の画像のように山の手線を描き出します。

f:id:mbaasdevrel:20181006142411p:plain

まとめ

iOSのMapKitで表示する際には位置情報オブジェクト(CLLocation)を作成し、さらにそれをMapKitのピンとなるMKPointAnnotationに展開します。後はmapViewに追加すればOKです。ここまでのコードはNCMBMania/locationApp at v1にアップしてあります。

位置情報や地図はアプリとの相性がとても良いです。ぜひmBaaSのデータストアを活用して位置情報アプリを開発してください。

中津川 篤司

中津川 篤司

NCMBエヴァンジェリスト。プログラマ、エンジニアとしていくつかの企業で働き、28歳のときに独立。 2004年、まだ情報が少なかったオープンソースソフトの技術ブログ「MOONGIFT」を開設し、毎日情報を発信している。2013年に法人化、ビジネスとエンジニアを結ぶDXエージェンシー「DevRel」活動をスタート。