WWDC Quick Look 💓 By SwiftGGTeam
What's new in CarPlay

What's new in CarPlay

元の動画を見る

Highlight

iOS 26 では widget と Live Activity が CarPlay App なしで車載画面に表示できるようになり、ナビゲーション App は 54 種類の maneuver タイプを通じて、ターン情報のメタデータをそのままダッシュボードや HUD に映し出せます。


主要内容

これまで CarPlay は開発者にとって敷居の高い入口でした。オーディオ、通信、ナビゲーションといった限られたカテゴリの entitlement を申請しなければ、車載スクリーンに App を載せることすらできませんでした。多くの App はそもそもこれらのカテゴリに該当せず、CarPlay 専用版をわざわざ作るモチベーションもないため、結果として車内のあのスクリーンと自分のプロダクトはまったく無縁のままでした。iOS 26 ではこの壁が取り払われます。systemSmall サイズの widget を実装している App、あるいは Live Activities を既に利用している App は、CarPlay App も entitlement もなしに、自動的に CarPlay Dashboard に表示されるようになります。

ドライバーは Dashboard を左にスワイプすると widget を確認でき、タッチスクリーン搭載の車種ではそのまま操作も可能です(02:27)。Live Activity は iPhone 側で開始されると自動的に Dashboard に表示され、Dashboard が表示されていない場合は CarPlay が画面下部に通知として貼り付け、重要な進捗を見逃さないようにします(05:23)。CarPlay は activity family small というサイズで描画します。未実装の場合は Dynamic Island の compact leading/trailing にフォールバックします。フードデリバリー、配車、フライト系の App にとっては、車載の表示枠を実質無料で手に入れられることになります。

2 つ目の軸は、既存の CarPlay App に対する機能強化です。リストテンプレートには pinned な headerGridButtons が追加され、Now Playing テンプレートはスポーツ試合モード(2 チーム + スコア + 試合時計)に対応、マップテンプレートはマルチタッチコールバック(pinch / pitch / rotate)を取得できるようになりました。中でも目玉はナビゲーションメタデータです。CPNavigationSession を通じて 54 種類の maneuver タイプと junction 角度を報告すると、車両側がダッシュボードや HUD に独自のデザイン言語で描画してくれます。App は具体的な見た目に一切関与する必要がありません。


詳細

widget を車載に載せるための最小手順: systemSmall family を実装するだけです。widget が車内シーンに不向きな場合(高密度なテキスト、密な操作が前提、Data Protection クラス A/B に依存など)は、disfavoredLocations で明示的に宣言します(03:21)。

// Disfavored locations modifier for CarPlay

WidgetConfiguration()
    .disfavoredLocations([.carPlay], for: [.systemSmall])

ポイント:

  • .disfavoredLocations([.carPlay], for: [.systemSmall]) は「この widget は CarPlay に向かない」とシステムに伝えるための宣言です。
  • 設定後も widget は CarPlay 設定画面に表示されますが、グルーピングされたうえで「未最適化」のラベルが付きます。
  • ドライバーが敢えて有効化した場合、widget の操作機能は無効化され、静的なコンテンツのみが表示されます。
  • disfavored として宣言するのが妥当なケース: ゲーム系の widget、タップで内容が更新される widget、メイン導線が CarPlay 非対応の App しかない widget など。

リストテンプレートの pinned 要素: リストの先頭に grid buttons を 1 行ピン留めできるようになりました(10:05)。

// Pinned elements

var headerGridButtons: [CPGridButton]?

// Create a Grid Button

class CPGridButton

init(titleVariants: [String],
     image: UIImage,
     handler: ((CPGridButton) -> Void)?)

ポイント:

  • headerGridButtonsCPListTemplate に追加された新しいプロパティで、設定すると最初の section の上に描画されます。
  • titleVariants は文字列の配列で、システムが利用可能な幅に応じて最適なバリアントを自動選択します。
  • handler クロージャはボタンがタップされたときに呼ばれます。
  • 通信系の App は CPMessageGridItemConfiguration(conversationIdentifier:unread:) を介して SiriKit の会話識別子と未読フラグを渡すこともできます。

ナビゲーションメタデータ: ナビゲーション App は delegate メソッドを 1 つ実装してサポートを宣言したうえで、maneuver と lane guidance を CPNavigationSession に前もって流し込みます(16:28)。

// Add support for metadata

// Declare support

func mapTemplateShouldProvideNavigationMetadata(_ mapTemplate: CPMapTemplate) -> Bool {
    true
}

// Provide maneuver information up-front

cpNavigationSession.add(maneuvers)
cpNavigationSession.add(laneGuidance)

// Reroute

cpNavigationSession.pauseTrip(for: .rerouting, description: "Rerouting")
cpNavigationSession.resumeTrip(updatedRouteInformation: cpRouteInformation)

ポイント:

  • mapTemplateShouldProvideNavigationMetadatatrue を返すことがメタデータ経路のスイッチであり、システムはこれを見て車両にターン情報を要求するかどうかを判断します。
  • cpNavigationSession.add(maneuvers) は後続の maneuver を一括で push し、1 件ずつ送ることによる遅延を避けます。CPManeuver は 54 種類のタイプをサポートし、直進、左右折、ランプの進入・退出、ラウンドアバウト、フェリーへの乗降などをカバーします(15:53)。
  • add(laneGuidance) は車線案内データを送信します。
  • ルートを再計算する際は pauseTrip(for: .rerouting, description:) で現在のルートを一時停止し、新しい CPRouteInformation を構築してから resumeTrip(updatedRouteInformation:) で切り替えます。
  • 描画は車両側が担当します。App はセマンティックなタイプ(straightAheadonRampoffRampenter_ferryarriveAtDestination など)を提供するだけで、実際の見た目はダッシュボードや HUD が独自に決定します(16:16)。

動作確認の経路: 実車は不要です。Additional Tools for Xcode に含まれる CarPlay Simulator をダウンロードし、USB で iPhone を Mac に接続すれば、フル体験を再現できます(06:25)。


重要ポイント

  • やること: 既存の systemSmall widget を CarPlay 向けに対応させる。

    • 取り組む価値: コストは極めて低く、containerBackgroundRemovable を一行追加してシステムフォントを確認するだけで、CarPlay Dashboard の表示枠を獲得できる場合もあります。CarPlay 対応カテゴリ外の App にとって、これは車載画面に乗る唯一の機会です。
    • 始め方: CarPlay Simulator で既存の widget を動かし、デフォルトの見た目を確認します。widget が高密度、操作前提、ロック画面のデータに依存している場合は、まず disfavoredLocations([.carPlay], for: [.systemSmall]) で宣言し、ドライバーが誤って有効化して体験を損ねるのを防ぎます。
  • やること: Live Activity に activity family small を実装する。

    • 取り組む価値: watchOS Smart Stack と CarPlay は同じサイズクラスを共有するため、一度対応すれば両方で丁寧にデザインされた表示が手に入ります。Dynamic Island compact からの劣化版を使い回す必要はありません。
    • 始め方: 現在の Live Activity の状態遷移を見直し、small サイズに残すのは「最も重要ないくつかの状態」のみに絞ります。CarPlay 上では非インタラクティブなので、ドライバーは一瞥するだけだと割り切る前提で設計します。
  • やること: ナビゲーション App に navigation metadata を組み込む。

    • 取り組む価値: ダッシュボードと HUD はドライバーの視線に最も近い場所であり、ターン情報をそこに投影することは UX 上の世代差を生みます。しかも車両との通信や状態管理は CarPlay 側が引き受けてくれます。
    • 始め方: mapTemplateShouldProvideNavigationMetadatatrue を返し、自前の maneuver タイプを Apple の 54 種類の enum にマッピング、cpNavigationSession.add(maneuvers) で前倒しにバッチ送信し、最後に CarPlay Simulator で動作を確認します。
  • やること: オーディオ App は audio session のライフサイクルを点検する。

    • 取り組む価値: CarPlay 環境では iPhone の音源、車載の FM / 衛星ラジオ、他の CarPlay App のオーディオが同居します。session を適切に deactivate しないと、他の音源を理由なく奪ってしまい、体験が大きく損なわれます(13:07)。
    • 始め方: コード中の AVAudioSession.setActive(true) をすべて検索し、それぞれに対応する setActive(false) があるかを確認します。さらに、アクティブ化のタイミングを「これから音声を再生する直前」まで絞り込みます。

関連 Session

  • Meet Liquid Glass — Liquid Glass は新しいデザイン言語であり、CarPlay の CPMapTemplate のボタンにも自動的に適用されます。
  • Wake up to the AlarmKit API — AlarmKit と Live Activities の組み合わせは、もう一つの「App なしで車載画面に乗せる」リマインド経路です。
  • Finish tasks in the background — バックグラウンド実行の仕組みが、車内での widget や Live Activity を適時に更新できるかどうかを左右します。

コメント

GitHub Issues · utterances