carplay
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCarPlay
CarPlay
Build apps that display on the vehicle's CarPlay screen using the CarPlay
framework's template-based UI system. Covers scene lifecycle, template
types, navigation guidance, audio playback, communication, point-of-interest
categories, entitlement setup, and simulator testing.
Targets Swift 6.3 / iOS 26+.
See references/carplay-patterns.md for extended patterns including full
navigation sessions, dashboard scenes, and advanced template composition.
使用CarPlay框架的基于模板的UI系统构建可在车载CarPlay屏幕上显示的应用。内容涵盖场景生命周期、模板类型、导航指引、音频播放、通讯、兴趣点分类、权限设置以及模拟器测试。目标环境为Swift 6.3 / iOS 26+。
查看 references/carplay-patterns.md 获取扩展模式,包括完整导航会话、仪表盘场景和高级模板组合。
Contents
目录
Entitlements and Setup
权限与设置
CarPlay requires a category-specific entitlement granted by Apple. Request it
at developer.apple.com/contact/carplay
and agree to the CarPlay Entitlement Addendum.
CarPlay需要苹果授予的特定分类权限。请在 developer.apple.com/contact/carplay 申请,并同意《CarPlay权限附加条款》。
Entitlement Keys by Category
按分类划分的权限密钥
| Entitlement | Category |
|---|---|
| Audio |
| Communication |
| Navigation |
| EV Charging |
| Parking |
| Quick Food Ordering |
| 权限 | 分类 |
|---|---|
| 音频 |
| 通讯 |
| 导航 |
| 电动车充电 |
| 停车 |
| 快速点餐 |
Project Configuration
项目配置
- Update the App ID in the developer portal under Additional Capabilities.
- Generate a new provisioning profile for the updated App ID.
- In Xcode, disable automatic signing and import the CarPlay provisioning profile.
- Add an with the entitlement key set to
Entitlements.plist.true - Set Code Signing Entitlements build setting to the path.
Entitlements.plist
- 在开发者门户的“额外功能”下更新App ID。
- 为更新后的App ID生成新的配置文件。
- 在Xcode中关闭自动签名,导入CarPlay配置文件。
- 添加文件,并将对应权限密钥设为
Entitlements.plist。true - 将“代码签名权限”构建设置设置为的路径。
Entitlements.plist
Key Types
核心类型
| Type | Role |
|---|---|
| UIScene subclass for the CarPlay display |
| Scene connect/disconnect lifecycle |
| Manages the template navigation hierarchy |
| Abstract base for all CarPlay templates |
| Vehicle display limits and content style |
| 类型 | 作用 |
|---|---|
| 用于CarPlay显示的UIScene子类 |
| 场景连接/断开的生命周期管理 |
| 管理模板导航层级 |
| 所有CarPlay模板的抽象基类 |
| 车载显示屏限制与内容样式 |
Scene Configuration
场景配置
Declare the CarPlay scene in and implement
to respond when CarPlay connects.
Info.plistCPTemplateApplicationSceneDelegate在中声明CarPlay场景,并实现以响应CarPlay连接事件。
Info.plistCPTemplateApplicationSceneDelegateInfo.plist Scene Manifest
Info.plist场景清单
plist
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<true/>
<key>UISceneConfigurations</key>
<dict>
<key>CPTemplateApplicationSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneClassName</key>
<string>CPTemplateApplicationScene</string>
<key>UISceneConfigurationName</key>
<string>CarPlaySceneConfiguration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).CarPlaySceneDelegate</string>
</dict>
</array>
</dict>
</dict>plist
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<true/>
<key>UISceneConfigurations</key>
<dict>
<key>CPTemplateApplicationSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneClassName</key>
<string>CPTemplateApplicationScene</string>
<key>UISceneConfigurationName</key>
<string>CarPlaySceneConfiguration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).CarPlaySceneDelegate</string>
</dict>
</array>
</dict>
</dict>Scene Delegate (Non-Navigation)
场景代理(非导航类)
Non-navigation apps receive an interface controller only. No window.
swift
import CarPlay
final class CarPlaySceneDelegate: UIResponder,
CPTemplateApplicationSceneDelegate {
var interfaceController: CPInterfaceController?
func templateApplicationScene(
_ templateApplicationScene: CPTemplateApplicationScene,
didConnect interfaceController: CPInterfaceController
) {
self.interfaceController = interfaceController
interfaceController.setRootTemplate(buildRootTemplate(),
animated: true, completion: nil)
}
func templateApplicationScene(
_ templateApplicationScene: CPTemplateApplicationScene,
didDisconnectInterfaceController interfaceController: CPInterfaceController
) {
self.interfaceController = nil
}
}非导航类应用仅会收到界面控制器,没有窗口。
swift
import CarPlay
final class CarPlaySceneDelegate: UIResponder,
CPTemplateApplicationSceneDelegate {
var interfaceController: CPInterfaceController?
func templateApplicationScene(
_ templateApplicationScene: CPTemplateApplicationScene,
didConnect interfaceController: CPInterfaceController
) {
self.interfaceController = interfaceController
interfaceController.setRootTemplate(buildRootTemplate(),
animated: true, completion: nil)
}
func templateApplicationScene(
_ templateApplicationScene: CPTemplateApplicationScene,
didDisconnectInterfaceController interfaceController: CPInterfaceController
) {
self.interfaceController = nil
}
}Scene Delegate (Navigation)
场景代理(导航类)
Navigation apps receive both an interface controller and a .
Set the window's root view controller to draw map content.
CPWindowswift
func templateApplicationScene(
_ templateApplicationScene: CPTemplateApplicationScene,
didConnect interfaceController: CPInterfaceController,
to window: CPWindow
) {
self.interfaceController = interfaceController
self.carWindow = window
window.rootViewController = MapViewController()
let mapTemplate = CPMapTemplate()
mapTemplate.mapDelegate = self
interfaceController.setRootTemplate(mapTemplate, animated: true,
completion: nil)
}导航类应用会同时收到界面控制器和。设置窗口的根视图控制器以绘制地图内容。
CPWindowswift
func templateApplicationScene(
_ templateApplicationScene: CPTemplateApplicationScene,
didConnect interfaceController: CPInterfaceController,
to window: CPWindow
) {
self.interfaceController = interfaceController
self.carWindow = window
window.rootViewController = MapViewController()
let mapTemplate = CPMapTemplate()
mapTemplate.mapDelegate = self
interfaceController.setRootTemplate(mapTemplate, animated: true,
completion: nil)
}Templates Overview
模板概述
CarPlay provides a fixed set of template types. The app supplies content;
the system renders it on the vehicle display.
CarPlay提供一组固定的模板类型。应用提供内容,系统负责在车载显示屏上渲染。
General Purpose Templates
通用模板
| Template | Purpose |
|---|---|
| Container with tabbed child templates |
| Scrollable sectioned list |
| Grid of tappable icon buttons (max 8) |
| Key-value info with up to 3 actions |
| Modal alert with up to 2 actions |
| Modal action sheet |
| 模板 | 用途 |
|---|---|
| 包含标签页子模板的容器 |
| 可滚动的分段列表 |
| 可点击图标按钮网格(最多8个) |
| 带最多3个操作的键值信息展示 |
| 带最多2个操作的模态弹窗 |
| 模态操作表 |
Category-Specific Templates
分类专属模板
| Template | Category |
|---|---|
| Navigation -- map overlay with nav bar |
| Navigation -- destination search |
| Audio -- shared Now Playing screen |
| EV Charging / Parking / Food -- POI map |
| Communication -- contact card |
| 模板 | 分类 |
|---|---|
| 导航类——带导航栏的地图覆盖层 |
| 导航类——目的地搜索 |
| 音频类——共享的正在播放屏幕 |
| 电动车充电/停车/点餐类——兴趣点地图 |
| 通讯类——联系人卡片 |
Navigation Hierarchy
导航层级
Use to add templates to the stack.
Use for modal display.
Use to go back.
must be set as root -- it cannot be pushed or presented.
pushTemplate(_:animated:completion:)presentTemplate(_:animated:completion:)popTemplate(animated:completion:)CPTabBarTemplate使用将模板添加到栈中。
使用展示模态模板。
使用返回上一级。
必须设为根模板——不能被推入或模态展示。
pushTemplate(_:animated:completion:)presentTemplate(_:animated:completion:)popTemplate(animated:completion:)CPTabBarTemplateCPTabBarTemplate
CPTabBarTemplate示例
swift
let browseTab = CPListTemplate(title: "Browse",
sections: [CPListSection(items: listItems)])
browseTab.tabImage = UIImage(systemName: "list.bullet")
let tabBar = CPTabBarTemplate(templates: [browseTab, settingsTab])
tabBar.delegate = self
interfaceController.setRootTemplate(tabBar, animated: true, completion: nil)swift
let browseTab = CPListTemplate(title: "Browse",
sections: [CPListSection(items: listItems)])
browseTab.tabImage = UIImage(systemName: "list.bullet")
let tabBar = CPTabBarTemplate(templates: [browseTab, settingsTab])
tabBar.delegate = self
interfaceController.setRootTemplate(tabBar, animated: true, completion: nil)CPListTemplate
CPListTemplate示例
swift
let item = CPListItem(text: "Favorites", detailText: "12 items")
item.handler = { selectedItem, completion in
self.interfaceController?.pushTemplate(detailTemplate, animated: true,
completion: nil)
completion()
}
let section = CPListSection(items: [item], header: "Library",
sectionIndexTitle: nil)
let listTemplate = CPListTemplate(title: "My App", sections: [section])swift
let item = CPListItem(text: "Favorites", detailText: "12 items")
item.handler = { selectedItem, completion in
self.interfaceController?.pushTemplate(detailTemplate, animated: true,
completion: nil)
completion()
}
let section = CPListSection(items: [item], header: "Library",
sectionIndexTitle: nil)
let listTemplate = CPListTemplate(title: "My App", sections: [section])Navigation Apps
导航应用
Navigation apps use . They are the only
category that receives a for drawing map content. The root
template must be a .
com.apple.developer.carplay-mapsCPWindowCPMapTemplate导航类应用使用权限。它们是唯一能获取用于绘制地图内容的分类。根模板必须是。
com.apple.developer.carplay-mapsCPWindowCPMapTemplateTrip Preview and Route Selection
行程预览与路线选择
swift
let routeChoice = CPRouteChoice(
summaryVariants: ["Fastest Route", "Fast"],
additionalInformationVariants: ["Via Highway 101"],
selectionSummaryVariants: ["25 min"]
)
let trip = CPTrip(origin: origin, destination: destination,
routeChoices: [routeChoice])
mapTemplate.showTripPreviews([trip], textConfiguration: nil)swift
let routeChoice = CPRouteChoice(
summaryVariants: ["Fastest Route", "Fast"],
additionalInformationVariants: ["Via Highway 101"],
selectionSummaryVariants: ["25 min"]
)
let trip = CPTrip(origin: origin, destination: destination,
routeChoices: [routeChoice])
mapTemplate.showTripPreviews([trip], textConfiguration: nil)Starting a Navigation Session
启动导航会话
swift
extension CarPlaySceneDelegate: CPMapTemplateDelegate {
func mapTemplate(_ mapTemplate: CPMapTemplate,
startedTrip trip: CPTrip,
using routeChoice: CPRouteChoice) {
let session = mapTemplate.startNavigationSession(for: trip)
session.pauseTrip(for: .loading, description: "Calculating route...")
let maneuver = CPManeuver()
maneuver.instructionVariants = ["Turn right onto Main St"]
maneuver.symbolImage = UIImage(systemName: "arrow.turn.up.right")
session.upcomingManeuvers = [maneuver]
let estimates = CPTravelEstimates(
distanceRemaining: Measurement(value: 5.2, unit: .miles),
timeRemaining: 900)
session.updateEstimates(estimates, for: maneuver)
}
}swift
extension CarPlaySceneDelegate: CPMapTemplateDelegate {
func mapTemplate(_ mapTemplate: CPMapTemplate,
startedTrip trip: CPTrip,
using routeChoice: CPRouteChoice) {
let session = mapTemplate.startNavigationSession(for: trip)
session.pauseTrip(for: .loading, description: "Calculating route...")
let maneuver = CPManeuver()
maneuver.instructionVariants = ["Turn right onto Main St"]
maneuver.symbolImage = UIImage(systemName: "arrow.turn.up.right")
session.upcomingManeuvers = [maneuver]
let estimates = CPTravelEstimates(
distanceRemaining: Measurement(value: 5.2, unit: .miles),
timeRemaining: 900)
session.updateEstimates(estimates, for: maneuver)
}
}Map Buttons
地图按钮
swift
let zoomIn = CPMapButton { _ in self.mapViewController.zoomIn() }
zoomIn.image = UIImage(systemName: "plus.magnifyingglass")
mapTemplate.mapButtons = [zoomIn, zoomOut]swift
let zoomIn = CPMapButton { _ in self.mapViewController.zoomIn() }
zoomIn.image = UIImage(systemName: "plus.magnifyingglass")
mapTemplate.mapButtons = [zoomIn, zoomOut]CPSearchTemplate
CPSearchTemplate示例
swift
extension CarPlaySceneDelegate: CPSearchTemplateDelegate {
func searchTemplate(_ searchTemplate: CPSearchTemplate,
updatedSearchText searchText: String,
completionHandler: @escaping ([CPListItem]) -> Void) {
performSearch(query: searchText) { results in
completionHandler(results.map {
CPListItem(text: $0.name, detailText: $0.address)
})
}
}
func searchTemplate(_ searchTemplate: CPSearchTemplate,
selectedResult item: CPListItem,
completionHandler: @escaping () -> Void) {
// Navigate to selected destination
completionHandler()
}
}swift
extension CarPlaySceneDelegate: CPSearchTemplateDelegate {
func searchTemplate(_ searchTemplate: CPSearchTemplate,
updatedSearchText searchText: String,
completionHandler: @escaping ([CPListItem]) -> Void) {
performSearch(query: searchText) { results in
completionHandler(results.map {
CPListItem(text: $0.name, detailText: $0.address)
})
}
}
func searchTemplate(_ searchTemplate: CPSearchTemplate,
selectedResult item: CPListItem,
completionHandler: @escaping () -> Void) {
// 导航至选中的目的地
completionHandler()
}
}Audio Apps
音频应用
Audio apps use . They display browsable
content in lists and use for playback controls.
com.apple.developer.carplay-audioCPNowPlayingTemplate音频类应用使用权限。它们在列表中展示可浏览内容,并使用提供播放控制。
com.apple.developer.carplay-audioCPNowPlayingTemplateNow Playing Template
正在播放模板
CPNowPlayingTemplateMPNowPlayingInfoCenterswift
let nowPlaying = CPNowPlayingTemplate.shared
nowPlaying.isUpNextButtonEnabled = true
nowPlaying.isAlbumArtistButtonEnabled = true
nowPlaying.updateNowPlayingButtons([
CPNowPlayingShuffleButton { _ in self.toggleShuffle() },
CPNowPlayingRepeatButton { _ in self.toggleRepeat() }
])
nowPlaying.add(self) // Register as CPNowPlayingTemplateObserverCPNowPlayingTemplateMPNowPlayingInfoCenterswift
let nowPlaying = CPNowPlayingTemplate.shared
nowPlaying.isUpNextButtonEnabled = true
nowPlaying.isAlbumArtistButtonEnabled = true
nowPlaying.updateNowPlayingButtons([
CPNowPlayingShuffleButton { _ in self.toggleShuffle() },
CPNowPlayingRepeatButton { _ in self.toggleRepeat() }
])
nowPlaying.add(self) // 注册为CPNowPlayingTemplateObserverSiri Assistant Cell
Siri助手单元格
Audio apps supporting can show an assistant cell.
Communication apps use with .
INPlayMediaIntentINStartCallIntent.startCallswift
let config = CPAssistantCellConfiguration(
position: .top, visibility: .always, assistantAction: .playMedia)
let listTemplate = CPListTemplate(
title: "Playlists",
sections: [CPListSection(items: items)],
assistantCellConfiguration: config)支持的音频应用可展示助手单元格。通讯类应用则使用配合。
INPlayMediaIntentINStartCallIntent.startCallswift
let config = CPAssistantCellConfiguration(
position: .top, visibility: .always, assistantAction: .playMedia)
let listTemplate = CPListTemplate(
title: "Playlists",
sections: [CPListSection(items: items)],
assistantCellConfiguration: config)Communication Apps
通讯应用
Communication apps use .
They display message lists and contacts, and support
for Siri-initiated calls.
com.apple.developer.carplay-communicationINStartCallIntentswift
let message = CPMessageListItem(
conversationIdentifier: "conv-123",
text: "Meeting at 3pm",
leadingConfiguration: CPMessageListItem.LeadingConfiguration(
leadingItem: .init(text: "Jane", textStyle: .abbreviated),
unread: true),
trailingConfiguration: CPMessageListItem.TrailingConfiguration(
trailingItem: .init(text: "2:45 PM")),
trailingText: nil, trailingImage: nil)
let messageList = CPListTemplate(title: "Messages",
sections: [CPListSection(items: [message])])通讯类应用使用权限。它们展示消息列表和联系人,并支持以实现Siri发起的通话。
com.apple.developer.carplay-communicationINStartCallIntentswift
let message = CPMessageListItem(
conversationIdentifier: "conv-123",
text: "Meeting at 3pm",
leadingConfiguration: CPMessageListItem.LeadingConfiguration(
leadingItem: .init(text: "Jane", textStyle: .abbreviated),
unread: true),
trailingConfiguration: CPMessageListItem.TrailingConfiguration(
trailingItem: .init(text: "2:45 PM")),
trailingText: nil, trailingImage: nil)
let messageList = CPListTemplate(title: "Messages",
sections: [CPListSection(items: [message])])Point of Interest Apps
兴趣点应用
EV charging, parking, and food ordering apps use
and to display locations and details.
CPPointOfInterestTemplateCPInformationTemplate电动车充电、停车和点餐类应用使用和展示地点及详情。
CPPointOfInterestTemplateCPInformationTemplateCPPointOfInterestTemplate
CPPointOfInterestTemplate示例
swift
let poi = CPPointOfInterest(
location: MKMapItem(placemark: MKPlacemark(
coordinate: CLLocationCoordinate2D(latitude: 37.7749,
longitude: -122.4194))),
title: "SuperCharger Station", subtitle: "4 available",
summary: "150 kW DC fast charging",
detailTitle: "SuperCharger Station", detailSubtitle: "$0.28/kWh",
detailSummary: "Open 24 hours",
pinImage: UIImage(systemName: "bolt.fill"))
poi.primaryButton = CPTextButton(title: "Navigate",
textStyle: .confirm) { _ in }
let poiTemplate = CPPointOfInterestTemplate(
title: "Nearby Chargers", pointsOfInterest: [poi], selectedIndex: 0)
poiTemplate.pointOfInterestDelegate = selfswift
let poi = CPPointOfInterest(
location: MKMapItem(placemark: MKPlacemark(
coordinate: CLLocationCoordinate2D(latitude: 37.7749,
longitude: -122.4194))),
title: "SuperCharger Station", subtitle: "4 available",
summary: "150 kW DC fast charging",
detailTitle: "SuperCharger Station", detailSubtitle: "$0.28/kWh",
detailSummary: "Open 24 hours",
pinImage: UIImage(systemName: "bolt.fill"))
poi.primaryButton = CPTextButton(title: "Navigate",
textStyle: .confirm) { _ in }
let poiTemplate = CPPointOfInterestTemplate(
title: "Nearby Chargers", pointsOfInterest: [poi], selectedIndex: 0)
poiTemplate.pointOfInterestDelegate = selfCPInformationTemplate
CPInformationTemplate示例
swift
let infoTemplate = CPInformationTemplate(
title: "Order Summary", layout: .leading,
items: [
CPInformationItem(title: "Item", detail: "Burrito Bowl"),
CPInformationItem(title: "Total", detail: "$12.50")],
actions: [
CPTextButton(title: "Place Order", textStyle: .confirm) { _ in
self.placeOrder() },
CPTextButton(title: "Cancel", textStyle: .cancel) { _ in
self.interfaceController?.popTemplate(animated: true,
completion: nil) }])swift
let infoTemplate = CPInformationTemplate(
title: "Order Summary", layout: .leading,
items: [
CPInformationItem(title: "Item", detail: "Burrito Bowl"),
CPInformationItem(title: "Total", detail: "$12.50")],
actions: [
CPTextButton(title: "Place Order", textStyle: .confirm) { _ in
self.placeOrder() },
CPTextButton(title: "Cancel", textStyle: .cancel) { _ in
self.interfaceController?.popTemplate(animated: true,
completion: nil) }])Testing with CarPlay Simulator
使用CarPlay模拟器测试
- Build and run in Xcode with the iOS simulator.
- Choose I/O > External Displays > CarPlay.
Default window: 800x480 at @2x. Enable extra options for navigation apps:
bash
defaults write com.apple.iphonesimulator CarPlayExtraOptions -bool YES- 在Xcode中构建并运行iOS模拟器。
- 选择I/O > 外部显示器 > CarPlay。
默认窗口:800x480 @2x。为导航应用启用额外选项:
bash
defaults write com.apple.iphonesimulator CarPlayExtraOptions -bool YESRecommended Test Configurations
推荐测试配置
| Configuration | Pixels | Scale |
|---|---|---|
| Minimum | 748 x 456 | @2x |
| Portrait | 768 x 1024 | @2x |
| Standard | 800 x 480 | @2x |
| High-resolution | 1920 x 720 | @3x |
Simulator cannot test locked-iPhone behavior, Siri, audio coexistence with
car radio, or physical input hardware (knobs, touch pads). Test on a real
CarPlay-capable vehicle or aftermarket head unit when possible.
| 配置 | 像素 | 缩放比 |
|---|---|---|
| 最小尺寸 | 748 x 456 | @2x |
| 竖屏 | 768 x 1024 | @2x |
| 标准 | 800 x 480 | @2x |
| 高分辨率 | 1920 x 720 | @3x |
模拟器无法测试iPhone锁定状态下的行为、Siri、与车载收音机的音频共存或物理输入硬件(旋钮、触控板)。尽可能在支持CarPlay的真实车辆或 aftermarket 主机上测试。
Common Mistakes
常见错误
DON'T: Use the wrong scene delegate method
错误:使用错误的场景代理方法
Navigation apps must implement
(with ). Non-navigation apps use
(no window). Using the wrong
variant produces no CarPlay UI.
templateApplicationScene(_:didConnect:to:)CPWindowtemplateApplicationScene(_:didConnect:)导航类应用必须实现(带)。非导航类应用使用(无窗口)。使用错误的方法会导致CarPlay界面无法显示。
templateApplicationScene(_:didConnect:to:)CPWindowtemplateApplicationScene(_:didConnect:)DON'T: Draw custom UI in the navigation window
错误:在导航窗口中绘制自定义UI
CPWindowCPWindowDON'T: Push or present CPTabBarTemplate
错误:推入或模态展示CPTabBarTemplate
CPTabBarTemplatesetRootTemplate(_:animated:completion:)CPTabBarTemplatesetRootTemplate(_:animated:completion:)DON'T: Instantiate CPNowPlayingTemplate
错误:实例化CPNowPlayingTemplate
Use . Creating a new instance causes issues.
CPNowPlayingTemplate.shared请使用。创建新实例会导致问题。
CPNowPlayingTemplate.sharedDON'T: Ignore vehicle display limits
错误:忽略车载显示屏限制
Check and respect
/ on list templates.
CPSessionConfiguration.limitedUserInterfacesmaximumItemCountmaximumSectionCount请检查,并遵守列表模板的/限制。
CPSessionConfiguration.limitedUserInterfacesmaximumItemCountmaximumSectionCountDON'T: Forget to call the completion handler
错误:忘记调用完成处理函数
CPListItem.handlerCPListItem.handlerReview Checklist
审核检查清单
- Correct CarPlay entitlement key in
Entitlements.plist - set to
UIApplicationSupportsMultipleScenestrue - scene in Info.plist
CPTemplateApplicationSceneSessionRoleApplication - Scene delegate class name matches
UISceneDelegateClassName - Correct delegate method used (with/without )
CPWindow - Root template set in before returning
didConnect - Interface controller and window references cleared on disconnect
- only used as root, never pushed
CPTabBarTemplate - used, not a new instance
CPNowPlayingTemplate.shared - /
maximumItemCountchecked before populating listsmaximumSectionCount - calls completion in every path
CPListItem.handler - Map-only content in root view controller (navigation apps)
CPWindow - App functions while iPhone is locked
- Tested at minimum, standard, and high-resolution simulator sizes
- Audio session deactivated when not actively playing
- 中使用正确的CarPlay权限密钥
Entitlements.plist - 设为
UIApplicationSupportsMultipleScenestrue - Info.plist中包含场景
CPTemplateApplicationSceneSessionRoleApplication - 场景代理类名与匹配
UISceneDelegateClassName - 使用了正确的代理方法(带/不带)
CPWindow - 在返回前设置了根模板
didConnect - 断开连接时清除了界面控制器和窗口引用
- 仅作为根模板使用,未被推入
CPTabBarTemplate - 使用而非新实例
CPNowPlayingTemplate.shared - 填充列表前检查了/
maximumItemCountmaximumSectionCount - 在所有路径中都调用了完成函数
CPListItem.handler - 根视图控制器中仅包含地图内容(导航类应用)
CPWindow - iPhone锁定时应用仍能正常工作
- 在最小、标准和高分辨率模拟器尺寸下进行了测试
- 非活跃播放时停用了音频会话
References
参考资料
- Extended patterns (dashboard, instrument cluster, full nav flow, tab composition): references/carplay-patterns.md
- CarPlay framework
- CPTemplateApplicationSceneDelegate
- CPInterfaceController
- CPMapTemplate
- CPListTemplate
- CPNowPlayingTemplate
- CPPointOfInterestTemplate
- CPNavigationSession
- Requesting CarPlay Entitlements
- Displaying Content in CarPlay
- Using the CarPlay Simulator
- CarPlay HIG
- 扩展模式(仪表盘、仪表集群、完整导航流程、标签页组合):references/carplay-patterns.md
- CarPlay framework
- CPTemplateApplicationSceneDelegate
- CPInterfaceController
- CPMapTemplate
- CPListTemplate
- CPNowPlayingTemplate
- CPPointOfInterestTemplate
- CPNavigationSession
- Requesting CarPlay Entitlements
- Displaying Content in CarPlay
- Using the CarPlay Simulator
- CarPlay HIG