Claude
Skills
Sign in
Back

carplay

Included with Lifetime
$97 forever

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.

Image & Video

What this skill does


# 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](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](#entitlements-and-setup)
- [Scene Configuration](#scene-configuration)
- [Templates Overview](#templates-overview)
- [Navigation Apps](#navigation-apps)
- [Audio Apps](#audio-apps)
- [Communication Apps](#communication-apps)
- [Point of Interest Apps](#point-of-interest-apps)
- [Testing with CarPlay Simulator](#testing-with-carplay-simulator)
- [Common Mistakes](#common-mistakes)
- [Review Checklist](#review-checklist)
- [References](#references)

## Entitlements and Setup

CarPlay requires a category-specific entitlement granted by Apple. Request it
at [developer.apple.com/contact/carplay](https://developer.apple.com/contact/carplay)
and agree to the CarPlay Entitlement Addendum.

### 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

1. Update the App ID in the developer portal under Additional Capabilities.
2. Generate a new provisioning profile for the updated App ID.
3. In Xcode, disable automatic signing and import the CarPlay provisioning profile.
4. Add an `Entitlements.plist` with the entitlement key set to `true`.
5. Set Code Signing Entitlements build setting to the `Entitlements.plist` path.

### 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

```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
    }
}
```

### Scene Delegate (Navigation)

Navigation apps receive both an interface controller and a `CPWindow`.
Set the window's root view controller to draw map content.

```swift
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

```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

```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 `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

```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(

Related in Image & Video