WWDC Quick Look 💓 By SwiftGGTeam
Turbocharge your app for CarPlay

Turbocharge your app for CarPlay

元の動画を見る

Highlight

iOS 26 では widget と Live Activity が CarPlay App なしでも車載画面に表示できるようになり、ナビゲーション App は 54 種類の maneuver メタデータをダッシュボードや HUD に送信できます。


主要内容

車載スクリーンはこれまで微妙な存在でした。ドライバーは試合のスコアをちらっと確認したい、充電の進捗を見たい、今日の天気を一目で把握したい。しかし、専用の CarPlay App を作っているメーカーしか画面に登場できず、大多数の App は車内では存在しないも同然でした。開発者にとっても、車載専用にエンジニアリングチームを割くだけの価値があるとは言えませんでした。

iOS 26 はこのハードルを取り払いました。App が systemSmall widget もしくは Live Activity に対応していれば、CarPlay Dashboard の左側に自動的に表示されます。新しい CarPlay 用プロジェクトを作る必要も、追加の entitlement を申請する必要もありません。ドライバーは「設定 → 一般 → CarPlay」でチェックを入れるだけで利用できます。Live Activity は車内では画面下部に通知として表示され、試合のゴールやデリバリーの到着といった重要なタイミングを見逃さずに済みます(05:07)。

本格的に CarPlay App を開発している方向けには、テンプレートシステムも強化されています。List テンプレートには headerGridButtons が追加され、よく使う項目を上部にピン留めできます。Now Playing テンプレートにはスポーツモードが加わり、両チームのスコアと試合の経過時間を車載画面にそのまま表示できます。マップテンプレートはマルチタッチジェスチャーに対応し、CarPlay Ultra ではターンメタデータをダッシュボードや HUD に送信して、メーカー側で独自にレンダリングできます。Apple は今回、「車載対応」を「重い投資が必要なプロジェクト」から「ついでにやれる小さな改修」へと位置付け直しました。


詳細

Widget の車載対応:modifier 一つで完結

widget はデフォルトで CarPlay にも転送されますが、すべてのケースに適しているわけではありません。たとえば頻繁な操作が必要なゲーム widget、あるいは Data Protection レベル A/B のデータに依存するコンテンツ(CarPlay は iPhone がロック中に使われることが多く、これらのデータを読めません)です。このような場合は disfavoredLocations を使って CarPlay を非推奨ロケーションとしてマークします(03:21)。

// Disfavored locations modifier for CarPlay

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

ポイント:

  • disfavoredLocations はロケーションの配列を受け取り、その widget が .carPlay で適切に動作しないことをシステムに伝えます。
  • for: [.systemSmall] で small サイズに限定しています。CarPlay は small のみ表示するため、他のサイズには影響しません。
  • マークされた widget は設定画面には表示されますが「最適化されていない」セクションにグループ化され、ドライバーが強制的に追加しても操作は無効化されます。

List テンプレート:主要な入口を上部にピン留め

iOS 26 では CPListTemplateheaderGridButtons プロパティが追加され、最初の list section の前にグリッド状のボタン列を表示できます(10:05)。

// Pinned elements

var headerGridButtons: [CPGridButton]?

// For Communication apps

class CPGridButton

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

class CPMessageGridItemConfiguration

init(conversationIdentifier: String, unread: Bool)

ポイント:

  • titleVariants は優先度順に並べたタイトル候補の配列です。車載画面は利用可能な幅に応じて最適なものを自動選択し、文字の切り詰めを回避します。
  • コミュニケーション系 App は CPMessageGridItemConfiguration を渡すことで conversationIdentifier を SiriKit に透過的に伝達でき、タップされた際に該当の会話に直接戻れます。
  • unread フィールドはボタンに未読を示す赤いドットを描画するため、ドライバーは新着メッセージの有無を一目で判断できます。

Now Playing スポーツモード:車載画面に試合スコアを

CarPlay の音声 App は iOS 18.4 以降、Now Playing をスポーツモードに切り替えて両チームの対戦情報を表示できます(11:20)。

// Now playing template with sports mode

let clock = CPNowPlayingSportsClock(elapsedTime: time, paused: false)

let status = CPNowPlayingSportsEventStatus(
    eventStatusText: ["1st"], // 1st quarter
    eventStatusImage: UIImage(named: "Semifinals"),
    eventClock: clock
)

let sports = CPNowPlayingModeSports(
    leftTeam: getLeftTeam(), // CPNowPlayingSportsTeam
    rightTeam: getRightTeam(), // CPNowPlayingSportsTeam
    eventStatus: status,
    backgroundArtwork: getBackgroundArtwork() // get UIImage
)

CPNowPlayingTemplate.sharedTemplate.nowPlayingMode = sports

ポイント:

  • CPNowPlayingSportsClock は開始時刻と停止状態を渡すだけで、システムが実時間に沿って自動的にカウントアップ/カウントダウンを行います。App 側で毎秒更新を送る必要はありません。
  • eventStatusText は文字列配列で試合のフェーズ(「1st」「準決勝」など)を渡せるため、多言語対応がしやすくなっています。
  • nowPlayingMode を設定した後はテンプレートオブジェクトを差し替える必要がなく、試合中もスコアやポゼッション表示をその場で更新できます。タイムシフト再生の際は対応する時刻のメタデータを同期するのを忘れないようにしましょう。

マルチタッチ:マップテンプレートのジェスチャーコールバック

CarPlay Ultra や一部の新型車はマルチタッチに対応しており、CPMapTemplate はズーム、ピッチ、回転のイベントをコールバックで App に渡します(14:15)。

// Multitouch

// Zoom callback

func mapTemplate(_ mapTemplate: CPMapTemplate,
                 didUpdateZoomGestureWithCenter center: CGPoint,
                 scale: CGFloat,
                 velocity: CGFloat) {     }

// Pitch callback

func mapTemplate(_ mapTemplate: CPMapTemplate,
                 pitchWithCenter center: CGPoint) {     }

// Rotate callback

func mapTemplate(_ mapTemplate: CPMapTemplate,
                 didRotateWithCenter center: CGPoint,
                 rotation: CGFloat,
                 velocity: CGFloat) {     }

ポイント:

  • center はマップビュー座標系におけるジェスチャーの中心点で、scale と組み合わせることでタッチ位置を基点としたズームを実装できます。
  • velocity はジェスチャーの速度を提供します。これを利用して慣性アニメーションを実装すれば、ズームや回転を停止する際の動きがより自然になります。
  • 3 つのコールバックは互いに独立しており、ピンチ、二本指の上下スワイプ、二本指の回転は同時に発生し得ます。App 側では複合ジェスチャーへの対応が必要です。

ナビゲーションメタデータ:54 種類の maneuver をダッシュボードへ

CarPlay Ultra では App がターン情報をダッシュボードや HUD に送信できます。ただし、実際の描画はメーカー側に委ねられ、App はセマンティクスの記述のみを担当します(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)

ポイント:

  • true を返すのがスイッチで、この App がメタデータを提供する意思があることをシステムに伝えます。返さない場合、ダッシュボードは空白のままになります。
  • add(maneuvers) で複数の maneuver をまとめて事前にコミットしたほうが、1 件ずつプッシュするより消費電力と CPU 使用率が抑えられます。特に長距離ルートで効果が大きくなります。
  • 経路を再計算する際は、まず pauseTrip(for: .rerouting) を呼ぶとダッシュボードに「再計算中」の状態が表示されます。新しいルートが準備できたら resumeTripCPRouteInformation を差し替えれば、画面のジャンプを防げます。
  • CPManeuver には 54 種類のタイプがあり、直進、右左折、ラウンドアバウト、ランプの出入り、フェリーへの乗船、目的地到着などのシーンを網羅します。メーカーはセマンティクスに基づいて独自のアイコンをレンダリングします(19:13)。

重要ポイント

  • やること:既存の widget に CarPlay 対応を追加し、まずは systemSmall を一つ通す。

    • なぜやる価値があるか:コストが極めて低く、車載画面という新しい表示枠が増えます。DAU に依存するツール系 App にとっては、ほぼタダで露出が増える施策です。
    • 始め方:widget がロック画面で取得できないデータに依存していないかを確認し、依存していれば disfavoredLocations で除外します。それ以外のケースでは widgetContentMarginscontainerBackgroundRemovable が設定済みかを確認するだけで十分です。
  • やること:既存の Live Activity を activity family small に対応させる。

    • なぜやる価値があるか:CarPlay は small サイズを優先的に表示します。これがない場合は Dynamic Island の compact leading/trailing にフォールバックされ、情報密度が大幅に下がってしまいます。
    • 始め方:watchOS Smart Stack 用のデザインを流用し、「最も重要な 1〜2 個の状態」のみを表示します。車内の Live Activity は操作不可である点も忘れないようにしましょう。
  • やること:ナビゲーション App は今すぐ mapTemplateShouldProvideNavigationMetadatatrue を返すようにする。

    • なぜやる価値があるか:CarPlay Ultra は中〜高級車種で展開が進んでおり、ダッシュボードはドライバーの視線が最も長く留まる場所です。メタデータを提供しない App はその画面では空っぽになってしまいます。
    • 始め方:既存の経路データを CPManeuver の配列に変換し、事前に CPNavigationSessionadd します。その後、Mac 上の CarPlay Simulator で動作確認を行いましょう。
  • やること:スポーツや試合系の音声 App は Now Playing スポーツモードに対応する。

    • なぜやる価値があるか:運転中に試合中継を聴くシーンでは、アルバムアートワークの代わりにスコアを表示するほうが自然で、静的なロゴと比べて情報量が桁違いになります。
    • 始め方:CPNowPlayingSportsClock を自前の試合時刻ソースに接続し、タイムシフト再生時にもスコアを同期させます。その他のフィールド(チームエンブレム、ステータステキストなど)は必要に応じて段階的に拡充していきます。

関連 Session

コメント

GitHub Issues · utterances