Search code examples
iosswiftavaudiosessionairplay

On iOS, how can I force AVRoutePickerView to allow route switching between speaker and the handset?


Right now, when the user presses the AVRoutePickerView, they get a choice of iPhone and other AirPlay targets. And picking iPhone uses the speakerphone to play back audio:

Current Situation

I'd like there to be an option to switch between iPhone and Speaker, where iPhone routes the audio to the internal handset speaker, and Speaker routes audio to the speakerphone. That's how other apps on the phone seem to work (Phone, Google Voice, and some others):

The way it should be


Solution

  • I figured it out, but I'm pretty pissed off at Apple for basically not having any documentation about how things are supposed to work!

    In essence, you have to overrideOutputAudioPort on AVAudioSession after calling setCategory, but before calling setActive. It doesn't matter which route you want to use for the override (.speaker or .none) -- either way, it'll now allow you to chose either the Speaker or iPhone in AVRoutePickerView. Here's an example:

    try AVAudioSession.sharedInstance().setCategory(.playAndRecord)
    try AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
    try AVAudioSession.sharedInstance().setActive(true)