How to Pause and Resume Your App’s Audio in Response to Turn-by-Turn Notifications and Other Audio from Other Apps
I’m writing this down if only so I can reference it myself later. Maybe this will help you, dear reader in some not-too-distant future. If you are making an iOS app that plays spoken-word audio (like, say, a podcast app) and you want your audio to pause when another app plays some audio (turn-by-turn directions notifications, etc.), then here is the TL;DR of what you need to do:
Your app’s audio session should use an appropriate category, most likely:
AVAudioSessionCategoryPlayback
.Your app’s audio session should use the
AVAudioSessionModeSpokenAudio
mode, which signals to AVFoundation that your audio session is primarily spoken word content which should ideally be interrupted by certain categories of audio from other apps’ audio sessions.Your app should register for the
.AVAudioSessionInterruption
notification (contrary to the documentation, don’t assume it’s fired on the main queue - be safe). In your handler for the notification, first check the user info to see whether the value forAVAudioSessionInterruptionTypeKey
is.began
or.ended
. If it’s.began
, then your audio player is likely already paused. You should update any other model or UI state accordingly. If the state is.ended
, then you should check the value forAVAudioSessionInterruptionOptions
to see if it contains.shouldResume
. If it does, you should resume playback. AVFoundation will not resume playback on your behalf.
Sadly, even if you do all these things, the final result is partially out of your control. The other app that triggered the interruption must configure its audio session with the option:
AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers
which signifies that it should mix with other audio sessions besides spoken audio, which should be interrupted. Apple’s Maps app does this. Google Maps does not. 😞
For more information, read this programming guide.