When developing an app with music, video, call functions, it always comes up this requirement:
How to select a desired audio device
Like the above image, it’s from CallKit where you can select the desired audio output from this action sheet.
First, we have to understand how many audio routes and how they switch. We will be based on developing a phone call app because it can involve both audio input and output.
iPhone: the iPhone handset is default route for a call.
Speaker: the speaker is the default output audio for like music, video, ring tone.
Bluetooth: whenever a bluetooth device connected, the bluetooth device will become the default audio route.
Headphones: whenever any headphones plugged in, it becomes the default audio route even there is also bluetooth device. And it overwrites the handset(iPhone) option, which means you cannot change to the handset(iPhone).
After figuring out the desired devices list and rule, we can conclude the design:
If there is no bluetooth device connected, we don’t need to provide the action sheet. Instead it can just toggle between handset(or headset) and speaker.
If there is any bluetooth devices connected, the action sheet will be
- Handset/Headset
- Speaker
- Bluetooth devices
How to get the desired AVAudioSessionPort
You can find the available input ports from AVAudioSession.sharedInstance().availableInputs
and find current routes(output) from
AVAudioSession.sharedInstance().currentRoute
And the below are the possible ports:
Headset mic: AVAudioSessionPortBuiltInMic
Headset output: AVAudioSessionPortBuiltInReceiver
Handset mic: AVAudioSessionPortHeadsetMic
Handset output: AVAudioSessionPortHeadphones
Speaker: AVAudioSessionPortBuiltInSpeaker
Bluetooth mic: AVAudioSessionPortBluetoothHFP
Bluetooth output: AVAudioSessionPortBluetoothHFP, AVAudioSessionPortBluetoothA2DP, AVAudioSessionPortBluetoothLE
How to bring up an action sheet dialog
Simply use UIAlertController with preferredStyle as .actionSheet
Alright! That’s it. Feel free to share your feedback or suggestion.