Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

Audio player app is silent if device connected via CarPlay

I have a SwiftUI app - (https://youtu.be/VbAfUk_eYl0?si=JxUBh0Bpb-vc1E1U) - which I thought was almost ready for release - a manager for airdropped audio files from Logic Pro or other music creation applications. It uses AVAudioEngine and AVAudioPlayerNode to play audio, and the MediaPlayer API to integrate with car audio and similar, all of which works well.

It does not currently have an explicit CarPlay integration (and I'm slightly horrified at the amount of work that is going to require).

I had the good or bad luck of getting a loaner car with carplay while mine is being repaired yesterday, and lo and behold, when connected to the vehicle via CarPlay, there is no audio output in the vehicle at all. The now playing panel correctly shows the information my app provides about the currently playing song; the player node believes it is playing, the AVAudioSession is configured as it should be. But there is no sound.

Obviously I cannot ship it in this state.

I've tried fiddling with the parameters the AVAudioSession is configured with, in case there was some parameter that was preventing audio output, to no avail - currently:

        var options = AVAudioSession.CategoryOptions()
        options.insert(.allowAirPlay)
        options.insert(.allowBluetooth)
        options.insert(.allowBluetoothA2DP)
        try session.setCategory(.playback, mode: .default, options: options)
        try? session.setPreferredIOBufferDuration(0.002) // ~96 samples at 44.1kHz
        try? session.setPrefersNoInterruptionsFromSystemAlerts(true)
        try? session.setPrefersInterruptionOnRouteDisconnect(false)
        try session.setActive(true, options: [.notifyOthersOnDeactivation])

All diagnostics within the app show the player operating correctly - files are played and flushed; AVAudioPlayerNodeCompletionCallbacks are called when they should be. But the output is not audible in the vehicle.

I would much prefer to ship this app without full-blown CarPlay integration, but with working audio when connected via CarPlay, and work on full CarPlay integration for the next release.

Is there some secret handshake I am just missing to make this work?

I found the culprit:

session.setPreferredIOBufferDuration(0.002)

Commenting out that line allows audio to play - but the system default buffer size is huge (likely to preserve battery life), resulting in an unacceptable 1/2 second delay when pausing the AVAudioPlayerNode. When I next have access to a vehicle with CarPlay I will try a few alternate buffer sizes and see if there is a happy medium - 2ms is a very small buffer size. If I discover anything useful I will post an update here.

Silent failure in the face of an incompatible setting isn't really ideal, especially when the setting is named preferred which implies that if the value passed can't work, it will be ignored.

Audio player app is silent if device connected via CarPlay
 
 
Q