CarPlay Now Playing integration patterns. Use when implementing CarPlay audio controls, CPNowPlayingTemplate customization, or debugging CarPlay-specific issues.
/plugin marketplace add CharlesWiltgen/Axiom/plugin install axiom@axiom-marketplaceThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Time cost: 15-20 minutes (if MPNowPlayingInfoCenter already working)
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.
| 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.
For custom playback controls beyond standard play/pause/skip:
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)
}
}
CarPlay requires an entitlement in your Xcode project:
Info.plist:
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>
Entitlements file:
<key>com.apple.developer.carplay-audio</key>
<true/>
Without the entitlement, CarPlay won't show your app at all.
| 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 |
Simulator (Xcode 12+):
Real Vehicle:
Requires entitlement approval from Apple (automatic for apps with UIBackgroundModes audio; no manual request needed).
Skills: axiom-now-playing, axiom-now-playing-musickit
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.