Interruptions are common in any type of software system. It is even more important in the case of mobile apps, starting with network interruptions to other common ones such as receiving calls or alarm notifications (also called audio interruption). Handling these audio interruptions will enhance the user experience gracefully.
Common types of audio interruptions
- Receiving incoming or making outgoing calls
- Alarm or timer notifications
- Other app takes over the iOS audio session (for example user opens a podcast app and starts playing it while your music app was playing)
How does the operating system handles interruption?
- Operating System deactivates your apps audio session
- Sends a notification through NSNotificationCenter saying an interruption has occurred. This will allow your app to gracefully respond to the interruption, for example, by pausing/stopping your playback and updating the UI states – such as display paused icon
- Once the interruption has ended, the operating system sends another notification confirming the interruption has ended. This will allow your app can respond to it (by resuming the playback and updating the UI state – display playing icon)
So basically, in order to handle these interruptions, all you need to do is listen to interruption notifications, and respond to it accordingly. Let’s see how.
Listening to audio interruption notifications
This can be done by adding an observer for AVAudioSession.interruptionNotification event.
private func addInterruptionsObserver() {
NotificationCenter.default.addObserver(self,
selector: #selector(handleInterruption),
name: AVAudioSession.interruptionNotification,
object: nil)
}
Make sure that your app’s AVAudioSession is set before this observer is added.
How to gracefully handle audio interruptions
Once the observer is set, handleAudioInterruption will now receive notifications when an interruption begins and ends.
@objc private func handleInterruption(notification: Notification) {
guard let userInfo = notification.userInfo,
let typeValue = userInfo[AVAudioSessionInterruptionTypeKey] as? UInt,
let type = AVAudioSession.InterruptionType(rawValue: typeValue) else {
return
}
switch type {
case .began:
// pause audio
// update player UI state to paused
case .ended:
// resume audio playback
// update player UI state to playing
// set audio session
default: break
}
}
If the AVAudioSession.InterruptionType == .ended
, there may also be extra info inside the userInfo
dictionary called AVAudioSession.InterruptionOptions which has a static property called shouldResume
. This tells you whether your app is ready to be resumed.
guard let optionsValue = userInfo[AVAudioSessionInterruptionOptionKey] as? UInt else {
return
}
let options = AVAudioSessionInterruptionOptions(rawValue: optionsValue)
if options.contains(.shouldResume) {
// Interruption Ended - playback should resume
}
And that’s it. Your app is now configured to handle audio interruptions gracefully.
Conclusion
Handling audio interruption is very essential to good user experience, and by listening to the events sent by iOS, it is an easy win for any media application.