Hi, I'm currently working on integrating CarPlay audio support for our existing news app. The goal is to choose an audio stream from a CPListTemplate, play the audio via AVPlayer and display the CPNowPlayingTemplate with the information I setup for MPNowPlayingInfoCenter.
My issue:
The CPNowPlayingTemplate is neither showing any kind of information nor does it respond to any button but the audio is playing as expected. Also the buttons don't reflect what I setup on MPRemoteCommandCenter.
I'm working on an iPhone 12 mini with iOS 16.0.2.
What I already checked:
- Entitlements-File includes com.apple.developer.carplay-audio and com.apple.developer.playable-content both set to true
- tried loading an artwork from URL as well as using a system icon
- tried to play different kinds of audio streams
- I'm calling beginReceivingRemoteControlEvents before AVPlayer starts playing the asset
- Same behavior with the new CarPlay Simulator and on a real audio device inside of a car
Here are some code snippets I'm using right now:
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
try? AVAudioSession.sharedInstance().setCategory(.playback)
try? AVAudioSession.sharedInstance().setActive(true)
UIApplication.shared.beginReceivingRemoteControlEvents()
self.player.pause()
let avAsset = AVAsset(url: asset.url)
let item = AVPlayerItem(asset: avAsset)
self.player = AVPlayer(playerItem: item)
self.player.play()
}
let artwork = MPMediaItemArtwork(boundsSize: image.size) { _ in
return image
}
var nowPlayingInfo = [String: Any]()
nowPlayingInfo = [
MPMediaItemPropertyTitle: title,
MPMediaItemPropertyArtist: artist,
MPMediaItemPropertyArtwork: artwork
]
DispatchQueue.main.async {
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
}
let commandCenter = MPRemoteCommandCenter.shared()
commandCenter.playCommand.isEnabled = true
commandCenter.pauseCommand.isEnabled = true
commandCenter.seekForwardCommand.isEnabled = false
commandCenter.seekBackwardCommand.isEnabled = false
commandCenter.playCommand.addTarget { [weak self] _ in
self?.player.play()
return .success
}
commandCenter.pauseCommand.isEnabled = true
commandCenter.pauseCommand.addTarget { [weak self] _ in
self?.player.pause()
return .success
}
let nowPlayingTemplate = CPNowPlayingTemplate.shared
guard interfaceController?.topTemplate != nowPlayingTemplate else { return }
if interfaceController?.templates.contains(nowPlayingTemplate) == true {
interfaceController?.pop(to: nowPlayingTemplate, animated: animated)
}
interfaceController?.pushTemplate(nowPlayingTemplate, animated: animated)
Thanks in advance for any kind of help!
Best Sven
After several days I've found the bug! Unintentionally I started the CarPlay App on the Simulator after I started a new debug build on iPhone in Xcode. But I missed, that Xcode showed an error, so I was launching the CarPlay App without having the debug process attached to Xcode. And suddenly everything works as expected. I can now reproduce it every time when I'm launching a new debug build from Xcode.
My workaround is to launch the new build, stop it and launch the App on CarPlay.
Anyway, debugging code is always possible so I never had the idea, that there is an issue. Only the CPNowPlayingTemplate isn't working while debugging.