home / skills / charleswiltgen / axiom / axiom-now-playing-carplay

This skill helps you implement CarPlay now playing integration by leveraging existing iOS MPNowPlayingInfoCenter and MPRemoteCommandCenter code.

npx playbooks add skill charleswiltgen/axiom --skill axiom-now-playing-carplay

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
4.3 KB
---
name: axiom-now-playing-carplay
description: CarPlay Now Playing integration patterns. Use when implementing CarPlay audio controls, CPNowPlayingTemplate customization, or debugging CarPlay-specific issues.
license: MIT
---

# CarPlay Integration

**Time cost**: 15-20 minutes (if MPNowPlayingInfoCenter already working)

## Key Insight

**CarPlay uses the SAME MPNowPlayingInfoCenter and MPRemoteCommandCenter as Lock Screen and Control Center.** If your Now Playing integration works on iOS, it automatically works in CarPlay with zero additional code.

## What CarPlay Reads

| iOS Component | CarPlay Display |
|---------------|-----------------|
| `MPNowPlayingInfoCenter.nowPlayingInfo` | CPNowPlayingTemplate metadata (title, artist, artwork) |
| `MPRemoteCommandCenter` handlers | CPNowPlayingTemplate button responses |
| Artwork from `nowPlayingInfo` | Album art in CarPlay UI |

No CarPlay-specific metadata needed. Your existing code works.

## CPNowPlayingTemplate Customization (iOS 14+)

For custom playback controls beyond standard play/pause/skip:

```swift
import CarPlay

@MainActor
class SceneDelegate: UIResponder, UIWindowSceneDelegate, CPTemplateApplicationSceneDelegate {

    func templateApplicationScene(
        _ templateApplicationScene: CPTemplateApplicationScene,
        didConnect interfaceController: CPInterfaceController
    ) {
        // ✅ Configure CPNowPlayingTemplate at connection time (not when pushed)
        let nowPlayingTemplate = CPNowPlayingTemplate.shared

        // Enable Album/Artist browsing (shows button that navigates to album/artist view in your app)
        nowPlayingTemplate.isAlbumArtistButtonEnabled = true

        // Enable Up Next queue (shows button that displays upcoming tracks)
        nowPlayingTemplate.isUpNextButtonEnabled = true

        // Add custom buttons (iOS 14+)
        setupCustomButtons(for: nowPlayingTemplate)
    }

    private func setupCustomButtons(for template: CPNowPlayingTemplate) {
        var buttons: [CPNowPlayingButton] = []

        // Playback rate button
        let rateButton = CPNowPlayingPlaybackRateButton { [weak self] button in
            self?.cyclePlaybackRate()
        }
        buttons.append(rateButton)

        // Shuffle button
        let shuffleButton = CPNowPlayingShuffleButton { [weak self] button in
            self?.toggleShuffle()
        }
        buttons.append(shuffleButton)

        // Repeat button
        let repeatButton = CPNowPlayingRepeatButton { [weak self] button in
            self?.cycleRepeatMode()
        }
        buttons.append(repeatButton)

        // Update template with custom buttons
        template.updateNowPlayingButtons(buttons)
    }
}
```

## Entitlement Requirement

CarPlay requires an entitlement in your Xcode project:

**Info.plist:**
```xml
<key>UIBackgroundModes</key>
<array>
    <string>audio</string>
</array>
```

**Entitlements file:**
```xml
<key>com.apple.developer.carplay-audio</key>
<true/>
```

Without the entitlement, CarPlay won't show your app at all.

## CarPlay-Specific Gotchas

| Issue | Cause | Fix | Time |
|-------|-------|-----|------|
| CarPlay doesn't show app | Missing entitlement | Add `com.apple.developer.carplay-audio` | 5 min |
| Now Playing blank in CarPlay | MPNowPlayingInfoCenter not set | Same fix as Lock Screen (Pattern 1) | 10 min |
| Custom buttons don't appear | Configured after push | Configure at `templateApplicationScene(_:didConnect:)` | 5 min |
| Buttons work on device, not CarPlay simulator | Debugger interference | Test without debugger attached | 1 min |
| Album art missing | Same as iOS issue | Fix MPMediaItemArtwork (Pattern 3) | 15 min |

## Testing CarPlay

**Simulator (Xcode 12+):**
1. I/O → External Displays → CarPlay
2. Tap CarPlay display
3. Find your app in Audio section
4. **Important**: Run without debugger for reliable testing (debugger can interfere with CarPlay audio session activation)

**Real Vehicle:**
Requires entitlement approval from Apple (automatic for apps with `UIBackgroundModes` audio; no manual request needed).

## Verification

- [ ] App appears in CarPlay Audio section
- [ ] Now Playing shows correct metadata
- [ ] Album artwork displays
- [ ] Play/pause/skip buttons respond
- [ ] Custom buttons (if any) appear and work
- [ ] Tested both with and without debugger

## Resources

**Skills**: axiom-now-playing, axiom-now-playing-musickit

Overview

This skill documents CarPlay Now Playing integration patterns for xOS audio apps. It explains why CarPlay uses the same Now Playing and remote command APIs as iOS, how to enable CarPlay-specific features like CPNowPlayingTemplate customization, and the entitlement and testing steps required to make your app appear and behave correctly in CarPlay.

How this skill works

CarPlay reads MPNowPlayingInfoCenter.nowPlayingInfo for metadata (title, artist, artwork) and uses MPRemoteCommandCenter handlers for button responses. CPNowPlayingTemplate mirrors that metadata and can be customized (iOS 14+) with album/artist, Up Next, and custom buttons. If your Now Playing integration works on iOS, it generally works in CarPlay with no extra playback code.

When to use it

  • Implementing audio playback controls that must work in CarPlay.
  • Adding custom CPNowPlayingTemplate buttons (playback rate, shuffle, repeat).
  • Debugging CarPlay-specific issues like blank Now Playing, missing artwork, or missing app listing.
  • Preparing entitlements and background audio settings for CarPlay deployment.
  • Testing CarPlay behavior in simulator or real vehicle during QA.

Best practices

  • Set MPNowPlayingInfoCenter.nowPlayingInfo and MPRemoteCommandCenter handlers exactly as you would for Lock Screen/Control Center.
  • Configure CPNowPlayingTemplate in templateApplicationScene(_:didConnect:) — not after pushing the template.
  • Include UIBackgroundModes audio in Info.plist and add com.apple.developer.carplay-audio entitlement before testing on vehicles.
  • Always test with and without the debugger attached; the debugger can interfere with CarPlay audio session activation.
  • Provide proper MPMediaItemArtwork to ensure album art displays in CarPlay.

Example use cases

  • Add a playback-rate toggle and update CPNowPlayingTemplate with CPNowPlayingPlaybackRateButton.
  • Expose Up Next and album/artist navigation by enabling template properties for a richer CarPlay UI.
  • Fix a blank Now Playing screen by ensuring nowPlayingInfo is set when playback starts.
  • Diagnose missing CarPlay app listing by verifying the carplay entitlement and background audio mode.
  • Test simulator CarPlay flow: External Displays → CarPlay, then run app without debugger for reliable behavior.

FAQ

Do I need CarPlay-specific metadata?

No. CarPlay reads the same nowPlayingInfo and remote commands you already set for iOS; no extra metadata is required.

Why don't my custom buttons appear in CarPlay?

Custom buttons must be configured when the CPTemplateApplicationScene connects. Configure them in templateApplicationScene(_:didConnect:).