Responding to Interruptions
Adding audio session code to handle interruptions ensures that your app’s audio continues behaving gracefully when a phone call arrives, a Clock or Calendar alarm sounds, or another app activates its audio session.
An audio interruption is the deactivation of your app’s audio session—which immediately stops your audio. Interruptions happen when a competing audio session from an app is activated and that session is not categorized by the system to mix with yours. After your session goes inactive, the system sends a “you were interrupted” message that you can respond to by saving state, updating the user interface, and so on.
Your app may be suspended following an interruption. This happens when a user accepts a phone call. If a user instead ignores a call, or dismisses an alarm, the system issues an “interruption ended” message, and your app continues running. For your audio to resume, you must reactivate your audio session.
The Interruption Life Cycle
Figure 3-1 illustrates the sequence of events before, during, and after an audio session interruption for a playback app.
An interruption event—in this example, the arrival of a FaceTime request—proceeds as follows. The numbered steps correspond to the numbers in the figure.
Your app is active, playing back audio.
A FaceTime request arrives. The system activates the FaceTime app’s audio session.
The system deactivates your audio session. At this point, playback in your app has stopped.
The system posts a notification, indicating that your session has been deactivated.
Your notification handler takes appropriate action. For example, it could update the user interface and save the information needed to resume playback at the point where it stopped.
If the user dismisses the interruption—ignoring the incoming FaceTime request—the system posts a notification, indicating that the interruption has ended.
Your notification handler takes action appropriate to the end of an interruption. For example, it might update the user interface, reactivate the audio session, and resume playback.
(Not shown in the figure.) If, instead of dismissing the interruption at step 6, the user accepts a phone call, your app is suspended.
Audio Interruption Handling Techniques
Handle interruptions by registering to observe interruption notifications posted by AVAudioSession
. What you do within your interruption code depends on the audio technology you are using and on what you are using it for—playback, recording, audio format conversion, reading streamed audio packets, and so on. Generally speaking, you need to ensure the minimum possible disruption, and the most graceful possible recovery, from the perspective of the user.
Table 3-1 summarizes appropriate audio session behavior during an interruption. If you use AVFoundation playback or recording objects, some of these steps are handled automatically by the system.
After interruption starts |
|
After interruption ends |
|
Table 3-2 summarizes how to handle audio interruptions according to technology. The rest of this chapter provides details.
Audio technology | How interruptions work |
---|---|
AVFoundation framework | The system automatically pauses playback or recording upon interruption and reactivates your audio session when you resume playback or recording. If you want to save and restore the playback position between app launches, save the playback position on interruption as well as on app quit. |
Audio Queue Services, I/O audio unit | These technologies put your app in control of handling interruptions. You are responsible for saving playback or recording position and for reactivating your audio session after the interruption ends. |
System Sound Services | Sounds played using System Sound Services go silent when an interruption starts. The sounds are eligible to be played again if the interruption ends. Apps cannot influence the interruption behavior for sounds that use this playback technology. |
Handling Interruptions from Siri
When Siri interrupts your app’s playback, you must keep track of any remote control commands issued by Siri while the audio session is in an interrupted state. During the interruption, keep track of any commands issued by Siri and respond accordingly when the interruption ends. For example, during the interruption, the user asks Siri to pause your app’s audio playback. When your app is notified that the interruption has ended, it should not automatically resume playing. Instead, your app’s UI should indicate that the app is in a paused state.
Observing Audio Interruptions
To handle audio interruptions, begin by registering to observe notifications of type AVAudioSessionInterruptionNotification
.
func registerForNotifications() { |
NotificationCenter.default.addObserver(self, |
selector: #selector(handleInterruption), |
name: .AVAudioSessionInterruption, |
object: AVAudioSession.sharedInstance()) |
} |
func handleInterruption(_ notification: Notification) { |
// Handle interruption |
} |
The posted NSNotification
instance contains a populated userInfo
dictionary providing the details of the interruption. You determine the type of interruption by retrieving the AVAudioSessionInterruptionType
value from the userInfo
dictionary. The interruption type indicates whether the interruption has begun or has ended.
func handleInterruption(_ notification: Notification) { |
guard let info = notification.userInfo, |
let typeValue = info[AVAudioSessionInterruptionTypeKey] as? UInt, |
let type = AVAudioSessionInterruptionType(rawValue: typeValue) else { |
return |
} |
if type == .began { |
// Interruption began, take appropriate actions (save state, update user interface) |
} |
else if type == .ended { |
guard let optionsValue = |
userInfo[AVAudioSessionInterruptionOptionKey] as? UInt else { |
return |
} |
let options = AVAudioSessionInterruptionOptions(rawValue: optionsValue) |
if options.contains(.shouldResume) { |
// Interruption Ended - playback should resume |
} |
} |
} |
If the interruption type is AVAudioSessionInterruptionTypeEnded
, the userInfo
dictionary might contain an AVAudioSessionInterruptionOptions
value. An options value of AVAudioSessionInterruptionOptionShouldResume
is a hint that indicates whether your app should automatically resume playback if it had been playing when it was interrupted. Media playback apps should always look for this flag before beginning playback after an interruption. If it’s not present, playback should not begin again until initiated by the user. Apps that don’t present a playback interface, such as a game, can ignore this flag and reactivate and resume playback when the interruption ends.
Responding to a Media Server Reset
The media server provides audio and other multimedia functionality through a shared server process. Although rare, it’s possible for the media server to reset while your app is active. Register for the AVAudioSessionMediaServicesWereResetNotification
notification to monitor for a media server reset. After receiving the notification, your app needs to do the following:
Dispose of orphaned audio objects (such as players, recorders, converters, or audio queues) and create new ones
Reset any internal audio states being tracked, including all properties of
AVAudioSession
When appropriate, reactivate the
AVAudioSession
instance using thesetActive:error:
method
You can also register for the AVAudioSessionMediaServicesWereLostNotification
notification if you want to know when the media server first becomes unavailable. However, most apps only need to respond to the reset notification. Use the lost notification only if the app must respond to user events that occur after the media server is lost, but before the media server is reset.
Copyright © 2017 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2017-09-19