Handling audio interruptions in your iOS app

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

  1. Receiving incoming or making outgoing calls
  2. Alarm or timer notifications
  3. 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?

  1. Operating System deactivates your apps audio session
  2. 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
  3. 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.

How useful was this post?

Click on a star to rate it!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?