Search code examples
iosmpnowplayinginfocentercarplaympremotecommandcentermpplayablecontentdelegate

CarPlay - Show Now Playing screen in iOS 13


My app is already the current "now playing app" on the phone (i.e. all the required info are provided to MPNowPlayingInfoCenter) and it correctly shows in the lock screen, with artist name, track title, artwork image, etc.

According to the docs, populating MPNowPlayingInfoCenter.default().nowPlayingInfo and adding the proper target/actions to MPRemoteCommandCenter should be enough to make sure your app is invoked in CarPlay when the user taps on the Now Playing icon.

On iOS 14 I managed to achieve the above by pushing CPNowPlayingTemplate to the stack, thanks to some clever tricks I found in this article.

On iOS 13 though, where everything is based on the dreadful MPPlayableContentManager APIs and no CPTemplateApplicationSceneDelegate methods are invoked for audio-based apps I simply cannot find a way to detect if/when the Now Playing screen will be displayed.

MPNowPlayingInfoCenter and MPRemoteCommandCenter are correctly configured - as said above - but my app is not picked up when tapping the Now Playing icon in CarPlay on iOS 13.

I thought this API would help me but I couldn't figure out how (it always returns an empty array).

The only workaround seems to be adding <key>UIBrowsableContentSupportsImmediatePlayback</key><true/> to your Info.plist: Now Playing gets correctly displayed but it starts playback immediately, which is not what I want.

Can anyone provide a working solution?


Solution

  • On pre-iOS 14 CarPlay we are setting the now playing identifiers (in our case just one since we don't have a playlist) after initiating playing:

    • MPPlayableContentManager.shared().nowPlayingIdentifiers = ["Some Id"]
    • This id should be the same id as the MPContentItem that initiated the playback (and has isPlayable set to true