チュートリアル : HERE マップを CarPlay に統合

このチュートリアルでは、Apple の CarPlay を使用して、車両のインフォテイメントディスプレイで MapView をレンダリングする方法を示します。 CarPlay を使用すると、車両の実際のハードウェアでアプリ を実行できます。 iOS シミュレータに沿って開発マシンで実行されている CarPlay シミュレータを使用して、シミュレーションを行うことができます。

このチュートリアルの結果として作成されるアプリ には、ズームインボタンとズームアウトボタンを備えた車内のヘッドユニットディスプレイにインスタンスMapView が表示されます。 MapView 別のインスタンスが、接続されているモバイル機器 またはシミュレータの画面に表示されます。 完成した HelloMapCarPlay のサンプルアプリ は 、 GitHub にあります。

一目で確認可能

HERE SDK では、特別な設定は不要です。 CarPlay 開発者ガイドに従って、他の API と同様に CarPlay と併用できます。 役立つリソースとして、Apple が提供する CarPlay API リファレンスおよび CarPlay プログラミングガイドも使用してください。

次の基本的な手順は、すべてのアプリ で共通です。

  1. AppDelegateで、CPWindowを取得するためのプロトコルCPApplicationDelegateを実装 します。
  2. UIViewController を作成 し、それをルートとしてCPWindowに設定します。
  3. アプリ を通常どおりビルドして実行します。 さらに、次のことが可能 :シミュレータのメインメニューから I/O -> 外部ディスプレイ -> CarPlay を経由して、CarPlay シミュレータを起動します。 その結果、 iPad または iPhone のシミュレータが 1 つのウインドウに、 CarPlay シミュレータが 2 つ目のウインドウに表示されます。

UIViewController では車内での使用について Apple の設計ガイドラインに従う必要があることを除き、特定の要件を満たす必要はありません。

アプリ を配布したり、実際のデバイスに展開したりするには、アプリ をアップルが確認する必要があります。 このため には、 CarPlay アプリ エンタイトルメントを作成し、 CarPlay エンタイトルメントの追補に同意する必要があります。

資格が Apple によって確認されるまで、 CarPlay アプリ を実デバイスにインストールすることはできません。 代わりに iOS デバイス シミュレータを使用してください。 テスト目的であっても、実際のデバイスに展開するには、資格で有効になっているプロビジョニングプロファイルが必要です。

既存の HERE SDK アプリ に CarPlay を統合

詳しく見て、新しい CarPlay アプリ を作成してみましょう。

このチュートリアルでは GitHub にある HelloMap アプリを使用します。 デフォルト では、デバイスにMapView が表示されます。 次に、このアプリ を拡張して、車内のヘッドユニットディスプレイにMapViewの 2 番目のインスタンスを表示します。 このためには、 CarPlay を統合する必要があります。

MapViewは通常のMapViewように動作します。 外観のカスタマイズ、 3D オブジェクトの追加、その他の HERE SDK エンジンの使用を行うことができますが、マップジェスチャはまだサポートされていません。 このため、地図を操作するにはボタンを追加する必要があります。

結果のアプリ は、テスト目的でのみ使用されます。 生産対応のアプリ については、CarPlay の設計ガイドラインに従って、車両環境に関連するアプリの設計方法を確認してください。

手順 1- CarPlay の資格を作成

このステップでは、ファイルEntitlements.plist を作成する必要があります。 アプリ の機能を指定し、アプリ ID にバインドされます。Xcode を使用して作成できます。 ここで説明されている手順に従ってください。 適切な資格を得るには、 Apple に連絡する必要があります。 シミュレータを使用した以下のテスト設定では、この設定はまだ必要ありません。

  1. Xcode で、Entitlements.plist という名前の新しいプロパティリスト ファイルを作成します。
  2. [ ビルドの設定 ] 、 [ コード署名のエンタイトルメント ] の順にクリックし、パスを "HelloMapCarPlay/Entitlements.plist" に設定します。

ファイルが次の場所にあることを確認してください。 HelloMapCarPlay/HelloMapCarPlay/Entitlements.plist - HERE 、 "HelloMapCarPlay" は、同じ名前の別のフォルダーに含まれるプロジェクト名です。 このフォルダにファイルを追加します。

Entitlements.plist ファイルを次のように編集します ( 後でアプリ の実際の要件に合わせて変更します ) 。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.developer.carplay-maps</key>
    <true/>
</dict>
</plist>

com.apple.developer.carplay-maps キーは、ターン・バイ・ターンナビ (矢印ナビ) アプリに必要なアプリケーションのスコープを示します。

手順 2- UIViewController を作成

UIViewController を使用してMapViewを表示します。 HelloMap の例アプリ には、 MapViewを示すクラスViewControllerがすでに含まれて います。 次に、 CarPlay で使用するためにのみインスタンス化された 2 番目のインスタンスを作成します。 ただし、コード単位では、クラスはまったく同じように見えます。

import heresdk
import UIKit

// This is the view controller shown on an in car's head unit display with CarPlay.
class CarPlayViewController: UIViewController {

    var mapView : MapView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Initialize MapView without a storyboard.
        mapView = MapView(frame: view.bounds)
        view.addSubview(mapView)

        // Load the map scene using a map scheme to render the map with.
        mapView.mapScene.loadScene(mapScheme: MapScheme.normalDay, completion: onLoadScene)
    }

    // Completion handler when loading a map scene.
    private func onLoadScene(mapError: MapError?) {
        guard mapError == nil else {
            print("Error: Map scene not loaded, \(String(describing: mapError))")
            return
        }

        // Configure the map.
        let camera = mapView.camera
        let distanceInMeters = MapMeasure(kind: .distance, value: 1000 * 7)
        camera.lookAt(point: GeoCoordinates(latitude: 52.518043, longitude: 13.405991), zoom: distanceInMeters)
    }

    public func zoomIn() {
        mapView.camera.zoomBy(2, around: mapView!.camera.principalPoint)
    }

    public func zoomOut() {
        mapView.camera.zoomBy(0.5, around: mapView!.camera.principalPoint)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        mapView.handleLowMemory()
    }
}

この新しい View Controller を使用 して、 2 つ目のインスタンス MapViewを作成します。 さらに、 zoomIn()zoomOut()の 2 つのズームメソッドを追加 し、マップとの基本的なやり取りを実装する方法を示します。 次のステップでは、ヘッドユニットのディスプレイに表示される 2 つのボタンを作成して、両方のメソッドを呼び出します。

パンなど、マップと対話するためのボタンを追加できます。 ただし 、ドライバーの注意を散漫にしないように、 Apple の デザインガイドラインに従ってください。 また、 マップ ビュー の上にビットマップグラフィックを表示できるようにするために、マップと一緒に移動、拡大縮小、またはチルトしないイメージをクラスMapImageOverlayと共にMapSceneにオーバーレイとして固定することもできます。

HERE SDK では、 CarPlay の地図ジェスチャはまだサポートされていません。 そのため、ボタンを使用して地図を操作する必要があります。 さらに、パンの動きなどのタッチジェスチャーをサポートしていない車もあります。 ノブおよびタッチパッドイベントでのジェスチャーのパニングの詳細については、『CarPlay プログラミングガイド』を参照してください。

ステップ 3- CarPlay ウィンドウを取得

MapViewを表示するには、新しいCarPlayViewController をrootとして設定する必要があります。

AppDelegate クラスを開き、次のインポートを追加します。

import CarPlay
import heresdk
import UIKit

次に、 CPApplicationDelegate プロトコルに準拠するようにクラスを適応させます。 2 つのメソッドを実装する必要があります。 最初のメッセージは、モバイル機器 がヘッドユニットのディスプレイに接続されたことを通知します。その結果、コンテンツを表示する CarPlay ウィンドウが表示されます。 2 番目の通知は、デバイスが切断されたときに送信されます。

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, CPApplicationDelegate {

    var window: UIWindow?
    let carPlayViewController = CarPlayViewController()
    let carPlayMapTemplate = CPMapTemplate()

    // Conform to CPApplicationDelegate, needed for CarPlay.
    func application(_ application: UIApplication,
                     didConnectCarInterfaceController interfaceController: CPInterfaceController,
                     to window: CPWindow) {
        // CarPlay window has been connected. Set up the view controller for it and a map template.
        carPlayMapTemplate.leadingNavigationBarButtons = [createButton(title: "Zoom +"),
                                                          createButton(title: "Zoom -")]
        interfaceController.setRootTemplate(carPlayMapTemplate, animated: true)
        window.rootViewController = carPlayViewController
    }

    private func createButton(title: String) -> CPBarButton {
        let barButton = CPBarButton(type: .text) { (button) in
            if (title == "Zoom +") {
                self.carPlayViewController.zoomIn()
            } else if (title == "Zoom -") {
                self.carPlayViewController.zoomOut()
            }
        }
        barButton.title = title
        return barButton
    }

    // Conform to CPApplicationDelegate, needed for CarPlay.
    func application(_ application: UIApplication,
                     didDisconnectCarInterfaceController interfaceController: CPInterfaceController,
                     from window: CPWindow) {
        // Override point for customization when disconnecting from car interface.
    }

    ...
}

CPApplicationDelegate により、CarPlayViewController インスタンスを rootViewControllerとして設定したCPWindowを受け取ることができます。これは、 CarPlay ウィンドウでコンテンツを管理するための基本ビューになります。

上に、 2 つのタイプCPBarButtonのボタンを定義するためのCPMapTemplate 作成します 。 Apple で CPMapTemplate は、タッチイベントの受信と処理も許可しています。 ボタンをクリックすると、イベントが View Controller に転送さ れ、MapViewがズームされます。

View Controller と同様 CPMapTemplate に、インスタンスをルートテンプレート に設定します。

AppDelegate クラスの REST は変更されません。

または 、『 CarPlay でのコンテンツの表示ガイド』を参照して、 CarPlay シーンを使用することもできます。

ここで、 [ シミュレータのビルドと実行 ] をクリックします。 シミュレータが起動したら、シミュレータのアプリ メニューを開き 、 [I/O] ->[External Displays] -> [CarPlay] を選択します。 2 つ目のウィンドウが開き、 CarPlay のホーム画面にアプリ が表示されます。

アプリの結果 は次のようになります。

スクリーンショット : CarPlay シミュレータで実行されている HERE マップを表示。

次に行く場所

このチュートリアルでは、既存のアプリ に CarPlay のサポートを追加する方法を示しました。デバイスとヘッドユニットの 2 つの個別の MapView インスタンスを実行しますが、両方の MapView インスタンスが同じアプリ ライフサイクル内で実行されるため、デバイスヘッドユニットの間で機能をハンドオーバーできます。 たとえば、自宅のモバイル機器でルートプランを作成し、車内 USB でデバイスを接続して運転を開始できます(アプリが Navigate Edition を使用している場合)。 ナビゲーションの進行状況は車両のヘッドユニットに表示され、デバイスは操作の詳細などのサポート情報を表示できます。

ドライバーの注意を散漫にしないように注意してください。 では、アプリ と対話するために音声コントロールを最前面に実装しないのはなぜでしょうか。 その他のアイデア :

  • ヘッドのユニットディスプレイに現在有効な制限速度を表示し、超過した場合に音響的に警告する速度調整アシスタントを追加します。
  • 現在走行中の道路のサポート道路属性情報を表示します。
  • ガソリンスタンド、レストラン、観光名所など、近隣のアプリ の場所情報を表示するを実装します。

」に一致する結果は 件です

    」に一致する結果はありません