mBaaSのデータストアでは位置情報を扱えます。位置情報なので、地図アプリや現実世界に合わせた情報を紹介するアプリなどに向いています。今回はデータストアを位置情報で検索して、返ってきた結果をMapKit上に表示します。
- iOS SDKを導入する
- MapKitを有効にする
- info.plistを更新する
- mBaaSを初期化する
- Main.storyboardにMapViewなどを追加する
- ViewControler.swiftにデリゲート追加
- タップした場所の位置情報を取得
- デモ
- まとめ
iOS SDKを導入する
イントロダクション (iOS) : クイックスタート | ニフクラ mobile backendを参考にiOS SDKを導入します。今回はCocoaPods版を導入しています。
MapKitを有効にする
XcodeのCapabilitiesタブでMapを有効にします。
info.plistを更新する
位置情報を扱うのでinfo.plistに項目を追加します。追加するのは以下の二つです。
- Privacy - Location When In Use Usage Description
- Privacy - Location Always and When In Use Usage Description
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
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 } }
タップした場所の位置情報を取得
タップジェスチャーをトラッキングして、handleTapというメソッドを呼び出します。
override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. // let gestureRecognizer = UITapGestureRecognizer(target: self, action:Selector("handleTap")) let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(gestureReconizer:))) gestureRecognizer.delegate = self as? UIGestureRecognizerDelegate mapView.addGestureRecognizer(gestureRecognizer) }
こうするとタップ時にhandpleTapが呼び出されます。
@objc func handleTap(gestureReconizer: UILongPressGestureRecognizer) { let location = gestureReconizer.location(in: mapView) let coordinate = mapView.convert(location,toCoordinateFrom: mapView)
そしてこのデータを使って NCMBGeoPoint
を作成します。
let geo = NCMBGeoPoint.init(latitude: coordinate.latitude, longitude: coordinate.longitude)
そして検索条件を作成します。今回はタップした場所から半径2キロとしています。
let query = NCMBQuery(className: "Station") query?.whereKey("geo", nearGeoPoint: geo, withinKilometers: 2)
後は検索を実行して、返ってきた結果をMapKit上に表示します。
query?.findObjectsInBackground({(objects, err) in let stations = objects as! [NCMBObject] var annotations: [MKPointAnnotation] = [] self.mapView.removeAnnotations(self.mapView.annotations) 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) })
デモ
実際に動かしているところです。タップする度に、その近くにある山の手線の駅を表示します。
まとめ
mBaaSを使うことで、位置情報検索が簡単に実現できます。データに位置情報を紐付けて保存し、自分がいる場所の近くの情報だけを検索すると言ったことも簡単にできるでしょう。ぜひ皆さんのアプリで活用してください!