【iOS Swift】地図アプリを作ろう!

画像001

概要

  • ニフクラ mobile backend(通称mBaaS)の『位置情報検索』機能を利用して、「現在地情報(緯度経度)をクラウドに保存する・保存したデータを取得して地図に表示する」内容を実装したサンプルプロジェクトです
  • 簡単な操作ですぐに ニフクラ mobile backendの機能を体験いただけます★☆

ニフクラ mobile backendって何??

スマートフォンアプリのバックエンド機能(プッシュ通知・データストア・会員管理・ファイルストア・SNS連携・位置情報検索・スクリプト)が開発不要、しかも基本無料(注1)で使えるクラウドサービス!

注1:詳しくはこちらをご覧ください

画像002

事前準備

動作環境

※下記内容で動作確認をしています

  • Mac OS X 10.10.5(Yosemite)
  • Xcode ver. 7.2.1
  • iPhone6 ver. 8.2
  • iPad mini ver.9.2
  • このサンプルアプリは、端末の位置情報を使用するため、実機ビルドが必要です

サンプルアプリ概要と使い方

画像005

  • 端末の位置情報を許可すると、位置情報の取得が開始されます
  • 起動時、地図は新宿駅を中心として表示されます
  • 現在地を表示するには、地図の現在地ボタンをタップします
  • 取得した位置情報(現在地)は右上の「保存」をタップすることでmBaaSに保存できます
  • 位置情報にタイトル・コメントをつけて保存が可能です
  • 保存した位置情報は地図上に青いマーカーで表示されます
  • また、「保存した場所をみる」ボタンをタップすると、既存お店情報と追加で保存した位置情報を地図に表示することができます
  • 全件検索・現在地から半径5km以内、1km以内の円形検索・新宿駅と西新宿駅の間の矩形検索が可能です

画像012

  • 事前にインポートしたお店とニフティ株式会社の位置情報を右下のボタンをタップすることで地図に表示可能です
  • 表示したマーカーを消す場合は左下のゴミ箱ボタンをタップします

サンプルアプリビルドまでの流れ

  1. サンプルプロジェクトのダウンロード
  2. CocoapodsでmBaaS SDKとGoogle Map SDKのインストール
  3. mBaaSでアプリ作成とAPIキーの発行
  4. mBaaSにお店データとアイコン画像をインポート
  5. Google Cloud platform でプロジェクトの作成とAPIキーの発行、Google Maps SDK for iOS の許可
  6. mBaaSとGoogle Map 双方のAPIキーを設定
  7. 実機ビルドして動作確認

作業手順

1. サンプルプロジェクトのダウンロード

下記リンクをクリックしてサンプルプロジェクトをダウンロードします▼

SwiftMapApp

  • フォルダを確認します

画像010

2. CocoapodsでmBaaS SDKとGoogle Map SDKのインストール

  • ダウンロードしたフォルダ内にある「SwiftMapApp.xcodeproj」と同じディレクトリにターミナル上で移動します
  • 注意:これをやっておかないと失敗します!
$ cd [指定ディレクトリ]
  • CocoaPodsを「はじめて使う場合」→ CocoaPodsをインストールする
$ sudo gem install cocoapods
  • CocoaPodsを「既にインストールしている場合」→CocoaPodsのバージョンアップをする
$ sudo gem update --system
  • インストールが初めての場合あるいは、アップグレードして最初の起動の場合はセットアップをする
$ pod setup
  • バージョン確認をします
  • 最新バージョンが確認できれば準備OKです
$ pod --version
  • 既存のPodfileにそれぞれのSDKをインストールする内容が記載してあります
  • Podfileの内容をインストールして、「workspace」を作成します
$ pod install --no-repo-update
  • フォルダを確認します
  • 下記のように、「Podfile.lock」ファイル, 「Pods」フォルダと「SwiftMapApp.xcworkspace」の3点が増えていることが確認できればOKです

画像011

3. mBaaSでアプリ作成とAPIキーの発行

  • ログイン後、下図のように「アプリの新規作成」画面が表示されるのでアプリを作成します

画像003

  • アプリ作成されると下図のような画面になります
  • この2種類のAPIキー(アプリケーションキーとクライアントキー)はXcodeで作成するiOSアプリにmBaaSを紐付けるために使用します

画像004

4. mBaaSにお店データとアイコン画像をインポート

  • ダウンロードしたプロジェクトフォルダ内にある「setting」フォルダ内のデータをmBaaSにインポートします

画像013

  • まず「Shop.json」をインポートして、mBaaSのデータストアにお店情報を保存します

画像008

※クラス名に「Shop」("S"は大文字)を指定していない場合、アプリからデータを読み込めませんのでご注意ください!

  • 下記のように5つのお店が登録されます

画像009

※ここで使用しているデータはデモのために作成した架空のもので、位置情報等も実在するお店とは関係ありませんので、ご了承ください。

  • 次に「image」フォルダ内にあるアイコン画像をファイルストアにインポートします
  • まとめてアップロードすることが可能です

画像015

  • 下記のように5つのお店のアイコンとmBaaSのアイコンが登録されます

画像016

5. Google Cloud platformでプロジェクトの作成とAPIキーの発行、Google Maps SDK for iOS の許可

  • Google Cloud platformにログインします
  • プリジェクトを作成します
  • プロジェクト名は任意で作成します 例)MapApp

画像GCP001

  • GoogleAPI呼び出し用のAPIキーを作成します

画像GCP002 画像GCP003 画像GCP004

  • Google Maps SDK for iOSを有効にします

画像GCP005

6. mBaaSとGoogle Map 双方のAPIキーを設定

  • 「SwiftMapApp.xcworkspace」をダブルクリックしてXcodeを起動します

画像014

  • プロジェクトが開いたら、AppDelegate.swiftを編集します
  • 先程mBaaSのダッシュボード上で確認したAPIキーとGoogle Cloud platformで発行したAPIキーを貼り付けます

画像007

  • それぞれYOUR_NCMB_APPLICATION_KEYYOUR_NCMB_CLIENT_KEYの部分を書き換えます
  • このとき、ダブルクォーテーション(")を消さないように注意してください!
  • 書き換え終わったらcommand + sキーで保存をします

7. 実機ビルドして動作確認

  • lightningケーブルで動作確認用端末をMacにつなぎます
  • 実機ビルドが初めての場合はこちらをご覧いただき、実機ビルドの準備をお願いします
  • Xcode画面で左上で、接続したiPhoneを選び、実行ボタン(さんかくの再生マーク)をクリックします

ビルド時にエラーが発生した場合の対処方法:Xcodeのバージョンが古い場合import NCMBにエラーが発生し、上手くSDKが読み込めないことがあります。その場合はXcodeのバージョンアップをお願いします。

  • アプリが起動したら、アプリ位置情報を許可します
  • 現在地の緯度経度と新宿駅を中心とした地図が表示されます
  • 現在地ボタンをタップすると現在地が表示されます

画像017

  • 右上の「保存」ボタンをタップすると位置情報の保存ができます
  • タイトルとコメントを記入するアラートが表示されますので、入力し「保存」をタップします

画像018

  • mBaaSに位置情報とタイトル・コメントが保存され、画面にマーカーが表示されます
  • マーカーをタップするとタイトル・コメントが表示されます

  • 保存に成功したら、mBaaSのダッシュボードから保存先の「データストア」を確認してみましょう!
  • 新しく「GeoPoint」クラスが作成され、その中にデータが保存されていることを確認できます
  • 下の例は、タイトルに「和食」、コメントに「ワンコインで食べられる!」と入れた場合です

画像019

  • 簡単に位置情報がクラウドに保存できました☆★
  • 他、保存した情報は「保存した場所をみる」ボタンで表示可能ですので触ってみてください!

解説

サンプルプロジェクトに実装済みの内容のご紹介

mBaaSの初期設定

【Swift版】ドキュメント(クイックスタート)

  • SDKの読み込みは下記のコードで行っています
import NCMB
  • SDKの初期化は下記のコードで行っています
// mBaaS APIkey
let applicationkey = "YOUR_NCMB_APPLICATIONKEY"
let clientkey = "YOUR_NCMB_CLIENTKEY"
// mBaaS初期化
NCMB.setApplicationKey(applicationkey, clientKey: clientkey)

※「YOUR_NCMB_APPLICATIONKEY」と「YOUR_NCMB_CLIENTKEY」は、mBaaSのダッシュボードで発行したAPIキーに置き換えます

Google Map を表示するための初期設定

  • SDKの詳しい導入方法は、Google Maps APIのiOS向け(Maps SDK for iOS)スタートガイド(日本語)をご活用ください

  • SDKの読み込みは下記のコードで行っています

import GoogleMaps
  • SDKの初期化は下記のコードで行っています
// Google Maps APIkey
let googleMapsAPIkey = "YOUR_GOOGLE_MAPS_APIKEY"
// GoogleMaps初期化
GMSServices.provideAPIKey(googleMapsAPIkey)

※「YOUR_GOOGLE_MAPS_APIKEY」は、Google Cloud Platformのダッシュボードで発行したAPIキーに置き換えます

位置情報取得のための設定

  • CoreLocation.frameworkを追加をし、ViewcControllerで読み込みをしています
import CoreLocation
  • Info.plistNSLocationWhenInUseUsageDescriptionを追記しています
  • Valueは任意の文字列が設定でき、位置情報許可アラート画面に表示されるものです

画像020

※コードの場合は<dict>~</dict>内に下記を追記

<key>NSLocationWhenInUseUsageDescription</key>
<string>Location Demo</string>

ロジックの紹介

  • Main.storyboardでデザインを作成し、ViewController.swiftにロジックを書いています
  • mBaaSに位置情報を保存するコードと取得するコードについて抜粋して紹介します

位置情報の保存・取得

  • 位置情報の保存
 /** 【mBaaS:データストア】位置情報の保存 **/
 // NCMBGeoPointの生成
let geoPoint = NCMBGeoPoint(latitude: atof(lat), longitude: atof(lon))
// NCMBObjectを生成
let object = NCMBObject(className: "GeoPoint")
// 値を設定
object.setObject(geoPoint, forKey: "geolocation")
object.setObject(title, forKey: "title")
object.setObject(snippet, forKey: "snippet")
// 保存の実施
object.saveInBackgroundWithBlock { (error: NSError!) -> Void in
    if error != nil {
        // 位置情報保存失敗時の処理

     } else {
         // 位置情報保存成功時の処理

    }
}

位置情報取得

  • 全件検索(検索条件なし)の場合
/** 【mBaaS:データストア(位置情報)】 保存データの取得 **/
// クラスの検索クエリを作成
let queryGeoPoint = NCMBQuery(className: "GeoPoint")
// データストアを検索
queryGeoPoint.findObjectsInBackgroundWithBlock({ (objects: Array!, error: NSError!) -> Void in
    if error != nil {
        // 検索失敗時の処理

    } else {
        // 検索成功時の処理

    }
})
  • 検索条件ありの場合
  • それぞれ以下のように検索条件を追加しています

<円形検索>

// 現在地から半径5km以内に該当する位置情報を検索
queryGeoPoint.whereKey("geolocation", nearGeoPoint: geoPoint, withinKilometers: 5.0)

<矩形検索>

// 新宿駅と西新宿駅の間
queryGeoPoint.whereKey("geolocation", withinGeoBoxFromSouthwest: shinjukuGeoPoint, toNortheast: westShinjukuGeoPoint)

参考