Carplay
Build CarPlay-enabled apps using the CarPlay framework. Use when creating navigation, audio, communication, EV charging, parking, or food ordering apps for the car display, working with CPTemplateApplicationScene, CPInterfaceController template hierarchies, CPListTemplate, CPMapTemplate, CPNowPlayingTemplate, configuring CarPlay entitlements, or integrating with CarPlay Simulator for testing.
- Skill ID
- dpearson2699/swift-ios-skills/carplay
- Publisher
- dpearson2699
- Repository
- swift-ios-skills
- Installs
- 0
- Files
- 3
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
dpearson2699/swift-ios-skills/carplayInstalls these files- SKILL.md
- evals/evals.json
- references/carplay-patterns.md
What this skill tells the agent
CarPlay
Build category-entitled, template-based CarPlay apps for the vehicle display. Scope: Swift 6.3, iOS 26+.
See references/carplay-patterns.md for extended patterns including full navigation sessions, dashboard scenes, and advanced template composition.
Scope boundary: full CarPlay framework apps use category entitlements, CPTemplateApplicationScene, CPTemplateApplicationSceneDelegate, CPInterfaceController, and system CPTemplate navigation. CarPlay-visible WidgetKit widgets and ActivityKit Live Activities are separate system experiences; route their implementation to those domains while keeping CarPlay-specific validation here.
Contents
- Entitlements and Setup
- Scene Configuration
- Templates Overview
- Navigation Apps
- Audio Apps
- Communication Apps
- Point of Interest Apps
- Testing with CarPlay Simulator
- Common Mistakes
- Review Checklist
- References
Entitlements and Setup
Request the category-specific entitlement from Apple's CarPlay entitlement form, accept the addendum, then provision the approved category key below.
Entitlement Keys by Category
| Entitlement | Category |
|---|---|
com.apple.developer.carplay-audio | Audio |
com.apple.developer.carplay-communication | Communication |
com.apple.developer.carplay-maps | Navigation |
com.apple.developer.carplay-charging | EV Charging |
com.apple.developer.carplay-parking | Parking |
com.apple.developer.carplay-quick-ordering | 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
Entitlements.plistwith the entitlement key set totrue. - Set Code Signing Entitlements build setting to the
Entitlements.plistpath.
Key Types
| Type | Role |
|---|---|
CPTemplateApplicationScene | UIScene subclass for the CarPlay display |
CPTemplateApplicationSceneDelegate | Scene connect/disconnect lifecycle |
CPInterfaceController | CarPlay-provided controller for setting the root template and pushing, presenting, or popping templates |
CPTemplate | Abstract base for all CarPlay templates |
CPSessionConfiguration | Vehicle display limits and content style |
Scene Configuration
Declare the CarPlay scene in Info.plist and implement CPTemplateApplicationSceneDelegate to respond when CarPlay connects.
Info.plist Scene Manifest
<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.
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 CPWindow. Set the window's root view controller to draw map content.
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.
General Purpose Templates
| Template | Purpose |
|---|---|
CPTabBarTemplate | Container with tabbed child templates |
CPListTemplate | Scrollable sectioned list |
CPGridTemplate | Grid of tappable icon buttons (max 8) |
CPInformationTemplate | Key-value info with up to 3 actions |
CPAlertTemplate | Modal alert with up to 2 actions |
CPActionSheetTemplate | Modal action sheet |
Category-Specific Templates
| Template | Category |
|---|---|
CPMapTemplate | Navigation -- map overlay with nav bar |
CPSearchTemplate | Navigation -- destination search |
CPNowPlayingTemplate | Audio -- shared Now Playing screen |
CPPointOfInterestTemplate | EV Charging / Parking / Food -- POI map |
CPContactTemplate | Communication -- contact card |
Navigation Hierarchy
Use pushTemplate(_:animated:completion:) to add templates to the stack. Use presentTemplate(_:animated:completion:) for modal display. Use popTemplate(animated:completion:) to go back. CPTabBarTemplate must be set as root -- it cannot be pushed or presented.
CPTabBarTemplate
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
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 com.apple.developer.carplay-maps. They are the only category that receives a CPWindow for drawing map content. The root template must be a CPMapTemplate.
Trip Preview and Route Selection
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
extension CarPlaySceneDelegate: CPMapTemplateDelegate {
func mapTemplate(_ mapTemplate: CPMapTemplate,More from dpearson2699
Use this skill in a project
Open any RiverX project, search the Skills panel for dpearson2699/swift-ios-skills/carplay, and install it in one click.
