この Codelab について
1. 始める前に
この Codelab では、Google Maps Platform Navigation SDK を使って、事前構成済みのデスティネーションに移動するシンプルな iOS アプリを作成する方法を学びます。
完成したアプリの外観は次のようになります。
前提条件
- Swift での iOS アプリ開発の基礎知識
- 特定の場所を中心とした地図の作成など、Google Maps SDK の基本コンセプトをある程度理解している。
学習内容
- Navigation SDK を使用して目的地にナビゲートするシンプルな iOS Swift アプリを作成する方法。
- リモートの Cocoapods リポジトリから Navigation SDK を統合する方法
- 位置情報の利用許可と Navigation SDK のエンドユーザー利用規約へのユーザー契約を管理する方法。
- SDK を初期化する方法。
- 目的地を設定してナビゲーション ガイダンスを開始する方法。
必要なもの
- XCode の最新の安定版。
- 課金が有効になっている Google アカウントとプロジェクト。
- iOS デバイス、または Xcode Simulator で動作するエミュレートされたデバイス。いずれの場合も、Navigation SDK の最小要件を満たしている必要があります。
2. セットアップする
課金を有効にした Google Cloud Platform アカウントとプロジェクトをまだ作成していない場合は、Google Maps Platform スタートガイドの手順に沿って Google Cloud プロジェクトを設定します。
コンソールで Google Cloud プロジェクトを選択する
Cloud コンソールでプロジェクトのプルダウン メニューをクリックし、この Codelab で使用するプロジェクトを選択します。
プロジェクトで Navigation SDK を有効にする
Google Cloud Marketplace で、この Codelab に必要な Google Maps Platform API と SDK を有効にします。
Google Cloud コンソールで [API とサービス] > [ライブラリ] に移動し、「Navigation SDK」を検索します。
1 件の検索結果が表示されます。
[Navigation SDK] をクリックして、プロダクトの詳細ページを開きます。[有効にする] をクリックして、プロジェクトで SDK を有効にします。
Google Maps SDK for iOS でもこのプロセスを繰り返します。
API キーを作成する
Cloud Console の [認証情報] ページで API キーを生成します。Google Maps Platform へのすべてのリクエストで API キーが必要になります。コンソールの [認証情報] ページ。[+ 認証情報を作成] をクリックします。[API キー] を選択します。選択します。
本番環境で使用する場合は、API キーにアプリケーション制限を設定することをおすすめしますが、この Codelab ではその設定は省略可能です。
3. サンプル プロジェクト ファイルを取得する
このセクションでは、この Codelab の GitHub リポジトリからファイルをクローンして、基本的な空の XCode アプリ プロジェクトを設定する方法について説明します。GitHub リポジトリには、Codelab コードの修正前と修正後のバージョンが含まれています。この Codelab は、空のプロジェクト テンプレートを使用して開始し、最終的に作成した状態にします。行き詰まった場合、リポジトリ内の完成したプロジェクトを参照として使用できます。
リポジトリのクローンを作成するか、コードをダウンロードする
Codelab を保存するディレクトリに移動します。
次に、リポジトリのクローンを作成するか、コードをダウンロードします。
git clone https://github.com/googlemaps-samples/codelab-navigation-101-ios-swift
git がインストールされていない場合は、次のボタンをクリックしてコードを取得します。
できるだけ早く演習を開始できるように、この Codelab で使用できるスターター コードがリポジトリの Starter
フォルダに用意されています。また、Solution
プロジェクトも完成しているので、いつでもここで作業を進めたり、進捗状況を確認したりできます。ソリューション プロジェクトを使用するには、「Cocoapods を使用してインストールする」の手順に沿ってインストールする必要があります。「pod update」コマンドを実行してからコマンドを solution/Navigation SDK Codelab
フォルダから削除します。
リポジトリのクローンをローカルに作成したら、XCode を使用して Starter
フォルダを既存のプロジェクトとして開きます。プロジェクトがビルドされて実行されたことを確認します。
デバイスを接続するか、XCode シミュレータをセットアップする
4. アプリに Navigation SDK を追加する
Navigation SDK を XCode プロジェクトに統合する方法は 3 つあります。この Codelab では CocoaPods を使用します。Swift Package Manager を使用して統合する方法や、SDK をダウンロードして手動でインストールする方法については、Navigation SDK ドキュメントの Xcode プロジェクトを作成して Navigation SDK をインストールするをご覧ください。
CocoaPods を使用してインストールする
CocoaPods ツールをまだインストールしていない場合は、ターミナルから次のコマンドを実行して macOS にインストールします。詳細については、CocoaPods スタートガイドをご覧ください。
sudo gem install cocoapods
プロジェクト フォルダの starter/Navigation SDK Codelab フォルダ内に Podfile という名前の新しいファイルを作成します(XCode で、[File] > [New] > [File] > [Other] > [Empty] を選択し、「Podfile」として保存します)。
Podfile
に次の内容を追加します。
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '15.0'
target 'Navigation SDK Codelab' do
pod 'GoogleNavigation', '9.1.1'
end
Podfile
割引されます。
ターミナルを開き、Podfile を保存した場所にディレクトリを変更します(これは、Codelab リポジトリの「starter/Navigation SDK Codelab」フォルダです)。
cd "<path-to-starter-project-folder>/Navigation SDK Codelab"
pod install
コマンドを実行します。これにより、Podfile
で指定された API が依存関係とともにインストールされます。
pod install
Xcode を終了し、プロジェクトの .xcworkspace ファイルを開いて Xcode を起動します。これ以降、プロジェクトを開くには .xcworkspace ファイルを使用する必要があります。
Pod ディレクトリがプロジェクト構造に追加され、「GoogleMaps」が含まれていることを確認する「GoogleNavigation」説明します。
API キーを追加する
次のように、API キーを AppDelegate.swift
に追加します。
- 次の import ステートメントを追加します。
import GoogleMaps
import GoogleNavigation
application(_:didFinishLaunchingWithOptions:)
メソッドに以下を追加します。
GMSServices.provideAPIKey("YOUR_API_KEY")
YOUR_API_KEYを、前のステップで作成した API キーに置き換えます。
プロジェクトをビルドして、エラーを修正します。
5. アプリの権限を構成する
Navigation SDK は、GPS 信号を利用して道路スナップ位置位置情報とターンバイターン方式のガイダンスを提供するため、アプリは正確な位置情報へのアクセスを許可するようユーザーに求める必要があります。
これを行うには、Xcode でアプリの Info.plist にプロパティを追加し、ランタイムでユーザーに権限をリクエストするコードをアプリに追加し、権限が付与されていない、位置情報が利用できないなどのエラーを処理します。
Xcode で Info.plist を開きます。次のようになります。
正確な位置情報の利用許可をリクエストする
[Information Property List] にカーソルを合わせると、新しい値を追加できます。[+] が表示されるまで行をアイコンが表示されます。[+] ボタンをプロパティ名の候補のダイアログが表示されますが、プロパティを手動で追加することもできます。
Info.plist に以下のプロパティと値を追加します。
プロパティ | 値 |
プライバシー - 位置情報の常に使用と使用時の使用の説明 | 「このアプリでターンバイターン方式ナビを提供するには、デバイスの位置情報が必要です」 |
プライバシー - 使用中の位置情報の使用の説明 | 「このアプリでターンバイターン方式ナビを提供するには、デバイスの位置情報が必要です」 |
allowsBackgroundLocationUpdates | はい |
バックグラウンドでの位置情報の利用許可をリクエストする
Info.plist に次のプロパティと値を追加します。
UIBackgroundModes
> [行を追加] > Item 0: App registers for location updates
(候補のプルダウン リストからこの値を選択)
完了すると、info.plist は次のようになります。
実行時に位置情報へのアクセスをリクエストする
次の import ステートメントを ViewController.swift
に追加します。
import GoogleNavigation
ViewController クラスに次の宣言を追加します。
var locationManager: CLLocationManager!
loadView()
のメソッド オーバーライドを追加して、locationManager.requestAlwaysAuthorization()
を呼び出します。
override func loadView() {
locationManager = CLLocationManager()
locationManager.requestAlwaysAuthorization()
これで、アプリはユーザーに位置情報をリクエストし、ユーザーが権限を付与すると、アプリで位置情報を利用できるようになります。
通知を表示する権限をリクエストする
loadView() に次のコードを追加して、通知を表示する権限をリクエストします。これは、ナビゲーション操作の指示を表示するために必要です。
UNUserNotificationCenter.current().requestAuthorization(options: [.alert]) {
granted, error in
// Handle denied authorization to display notifications.
if !granted || error != nil {
print("User rejected request to display notifications.")
}
}
アプリをビルドして実行し、位置情報の共有と通知の有効化を求めるメッセージが表示されることを確認します。
6. ナビゲーション ユーザー インターフェースを追加する
このステップでは、地図を追加して、場所を表示するように構成します。次に、Navigation SDK の利用規約がダイアログに表示されます。
アプリにマップビューを追加する
ViewController に GMSMapView 変数を宣言する次の行を追加します。
var mapView: GMSMapView!
Viewcontroller.swift
の loadView()
に次のコードを追加して、地図を初期化します。
let camera = GMSCameraPosition.camera(withLatitude: 51.483174, longitude: -0.177369, zoom: 14)
let options = GMSMapViewOptions()
options.camera = camera
options.frame = .zero
mapView = GMSMapView(options: options)
view = mapView
アプリをビルドして実行すると、ロンドン南西部を中心とする地図が表示されます。
Navigation SDK プロダクトの利用規約ダイアログを表示する
前のコードと同じ loadView()
メソッドの ViewController.swift
に次のコードを追加します。Navigation SDK のエンドユーザー向け利用規約が表示されます。同意しないと、ナビゲーションは有効になりません。
// Show the terms and conditions.
let companyName = "Navigation SDK Codelab"
GMSNavigationServices.showTermsAndConditionsDialogIfNeeded(withCompanyName: companyName) { termsAccepted in
if termsAccepted {
// Enable navigation if the user accepts the terms.
self.mapView.isNavigationEnabled = true
// Request authorization for alert notifications which deliver guidance instructions
// in the background.
} else {
// Handle the case when the user rejects the terms and conditions.
}
}
アプリをビルドして実行し、ダイアログを表示します。
7. 重要なナビゲーション イベントのリスナーを追加する
このステップでは、目的地への到着やドライバーによるルートの変更など、重要なイベントのリスナーを設定する方法について説明します。
これらのイベントをリッスンするには、ビュー コントローラで GMSNavigatorListener
プロトコルを採用する必要があります。
このプロトコルを ViewController.swift
のクラス定義に追加します。
class ViewController: UIViewController,
GMSNavigatorListener {
次に、loadView():
でリスナーを設定するコード行を追加します。
// Add a listener for GMSNavigator.
mapView.navigator?.add(self)
最後に、発生したイベントを処理する 2 つのメソッドをクラスに追加します。
// Listener to handle arrival events.
func navigator(_ navigator: GMSNavigator, didArriveAt waypoint: GMSNavigationWaypoint) {
print("You have arrived at: \(waypoint.title)")
}
// Listener for route change events.
func navigatorDidChangeRoute(_ navigator: GMSNavigator) {
print("The route has changed.")
}
8. 目的地を設定してガイダンスを開始する
このセクションでは、デスティネーションを設定し、ナビゲーション ガイダンスを開始する方法について説明します。
ナビゲーション ロジック用の新しい関数を作成します。
まず、startNav()
という新しい関数を ViewController
に追加します。これには、目的地を設定してナビゲーションを開始するロジックが含まれます。
// Create a route and start guidance.
@objc func startNav() {
}
デスティネーションの Waypoint
を作成します。
次に、1 つのウェイポイントを含む目的地の配列を作成します。
// Create a route and start guidance.
@objc func startNav() {
var destinations = [GMSNavigationWaypoint]()
destinations.append(
GMSNavigationWaypoint.init(
placeID: "ChIJH-tBOc4EdkgRJ8aJ8P1CUxo",
title: "Trafalgar Square")!)
}
setDestinations()
を呼び出してレスポンスを処理します。
次に、setDestinations
を呼び出して、返された GMSRouteStatus
を処理します。
GMSRouteStatus
が「OK」の場合は、mapView
の navigator
オブジェクトに isGuidanceActive=true
を設定してガイダンスを開始します。そうでない場合は、エラーがあったことを示すステートメントを出力します。
返された GMSRouteStatus
値が「OK」の場合は、mapView.locationSimulator.simulateLocationsAlongExistingRoute()
を呼び出してルート沿いの運転をシミュレートします。
// Create a route and start guidance.
@objc func startNav() {
var destinations = [GMSNavigationWaypoint]()
destinations.append(
GMSNavigationWaypoint.init(
placeID: "ChIJH-tBOc4EdkgRJ8aJ8P1CUxo",
title: "Trafalgar Square")!)
mapView.navigator?.setDestinations(
destinations
) { routeStatus in
guard routeStatus == .OK else {
print("Handle route statuses that are not OK.")
return
}
//If routeStatus is OK, start guidance.
self.mapView.navigator?.isGuidanceActive = true
//start simulating driving along the route. self.mapView.locationSimulator?.simulateLocationsAlongExistingRoute()
self.mapView.cameraMode = .following
}
}
一般的なエラー ステータスを処理する
特に新しいアプリで初期の問題をデバッグする場合は、GMSRouteStatus
エラーをより明示的に処理することをおすすめします。たとえば、位置情報の利用許可、API キー、「ルートが見つかりません」というメッセージが表示されることがあります。エラーの発生頻度が高くなるため、このようなエラー状態を処理すると便利です。
これらの特定のケースを処理し、コンソールにステートメントを出力するコードを追加します。
mapView.navigator?.setDestinations(
destinations
) { routeStatus in
guard routeStatus == .OK else {
print("Handle route statuses that are not OK.")
switch routeStatus {
case .locationUnavailable:
print("Location unavailable.") //check permissions
case .noRouteFound:
print("No route found.") //check start location and destination
case .waypointError:
print("Waypoint error") //check Place ID
default:
print("Not sure what happened")
}
return
}
ナビゲーション ガイダンスを開始するボタンを追加する
最後に、UI にボタンを追加して startNav メソッドに接続します。以下のコードを使用して、makeButton()
というメソッドを作成します。loadView()
から makeButton()
関数を呼び出します。
// Add a button to the view.
func makeButton() {
// A button to start navigation.
let navButton = UIButton(frame: CGRect(x: 5, y: 150, width: 200, height: 35))
navButton.backgroundColor = .blue
navButton.alpha = 0.5
navButton.setTitle("Start navigation", for: .normal)
navButton.addTarget(self, action: #selector(startNav), for: .touchUpInside)
self.mapView.addSubview(navButton)
}
アプリをビルドして実行します。
注: terraform plan または
startNav()
は
setDestinations()
方法では、最初の 1,000 件の宛先を超えると料金が発生します。詳しくは、使用量と請求額をご覧ください。
9. お疲れさまでした
目的地に到着しました。
Google Maps Platform Navigation SDK を使用して、目的地までのターンバイターン ナビゲーション ガイダンスを提供するシンプルなアプリを作成しました。
アプリの権限と Navigation SDK エンドユーザー規約ダイアログを設定し、プレイス ID を使用してデスティネーションを指定しました。アプリで、さまざまな成功状態とエラー状態に対処しました。
10. さらに改善する
アプリ開発をさらに進める場合は、以下のトピックを参考にしてください。
- その他のナビゲーション イベントをリッスンする。残りの時間または距離がしきい値を超えた場合にメッセージを表示するコードを追加します。
- ナビゲーション インターフェースをカスタマイズする。
- さらに大きな問題に挑戦したい場合は、Places API の Place Picker を追加して、ユーザーが目的地を設定できるようにしてみましょう。ヒント: Navigation SDK のデモアプリにはサンプル実装が含まれています。プロジェクト フォルダで
pod try GoogleNavigation
を実行して、コードを確認します。