Working with Categories

An audio session category is a key that identifies a set of audio behaviors for your app. By setting a category, you indicate your audio intentions to the system—such as whether your audio should continue when the Ringer/Silent switch is flipped. The seven audio session categories in iOS, along with a set of override and modifier switches, let you customize your app’s audio behavior.

Each audio session category specifies a particular pattern of “yes” and “no” for each of the following behaviors, as detailed in Table B-1:

Most apps only need to set the category once, at launch. That said, you can change the category as often as you need to, and can do so whether your session is active or inactive. If your session is inactive, the category request is sent when you activate your session. If your session is already active, the category request is sent immediately.

Choosing the Best Category

The precise behaviors associated with each category are not under your app’s control, but rather are set by the operating system. Apple may refine category behavior in future versions of iOS. Your best strategy is to pick the category that most accurately describes your intentions for the audio behavior you want. The appendix, Audio Session Categories and Modes, summarizes behavior details for each category.

To pick the best category, consider:

The following list describes the categories and the audio behavior associated with them. The AVAudioSessionCategoryAmbient category allows other audio to continue playing; that is, it is a mixable app. The remaining categories indicate that you want other audio to stop when your session becomes active. However, you can customize the non-mixing “playback” and “play and record” categories to allow mixing, as described in Fine-Tuning a Category.

Expanding Options Using the Multiroute Category

The multiroute category works slightly differently than the other categories. All categories follow the “last in wins” rule, where the last device plugged into an input or output route is the dominant device. However, the multiroute category enables the app to use all of the connected output ports instead of only the last-in port. For example, if you are listening to audio through the HDMI output route and plug in a set of headphones, the audio plays through the headphones. Your app can continue playing audio through the HDMI output route while also playing audio through the headphones.

Your app can send different audio streams to different output routes. For example, your app could send one audio stream to the left headphone, another audio stream to the right headphone, and a third audio stream to the HDMI routes. Figure 2-1 shows an example of sending multiple files to different audio routes.

Figure 2-1  Sending different files to different audio routes

Depending on the device and any connected accessories, the following are valid output route combinations:

The multiroute category supports the use of a single input port.

Setting Your Audio Session Category

For most iOS apps, setting your audio session category at launch—and never changing it—works well. This provides the best user experience because the device’s audio behavior remains consistent as your app runs.

To set the audio session category, call the setCategory:error: method as shown in Listing 2-1. For descriptions of all the categories, refer to Choosing the Best Category.

Listing 2-1  Setting the audio session category using the AV Foundation framework

NSError *setCategoryError = nil;
BOOL success = [[AVAudioSession sharedInstance]
                setCategory: AVAudioSessionCategoryAmbient
                      error: &setCategoryError];
 
if (!success) { /* handle the error in setCategoryError */ }

Using Modes to Specialize the Category

While categories set the base behaviors for your app, modes are used to specialize an audio session category. Set the mode for a category to further define the audio behaviors of your app. There are seven modes to choose from:

Choosing Categories and Modes for AirPlay

Only specific categories and modes support AirPlay. The following categories support both the mirrored and non-mirrored versions of Airplay:

The AVAudioSessionCategoryPlayAndRecord category only supports mirrored Airplay.

Modes only support AirPlay when used in conjunction with the play-and-record category. The following modes support AirPlay mirroring only:

Fine-Tuning a Category

You can fine-tune an audio session category in a variety of ways. Depending on the category, you can:

You can override the interruption characteristic of the AVAudioSessionCategoryPlayback, AVAudioSessionCategoryPlayAndRecord, and AVAudioSessionCategoryMultiRoute categories so that other audio is allowed to mix with yours. To perform the override, apply the AVAudioSessionCategoryOptionMixWithOthers property to your audio session. When you set your app to be mixable, your app will not interrupt audio from other non-mixable apps when its audio session goes active. Also, your app’s audio will not be interrupted by another app’s non-mixable audio session, for example the Music app.

You can programmatically influence the audio output route. When using the AVAudioSessionCategoryPlayAndRecord category, audio normally goes to the receiver (the small speaker you hold to your ear when on a phone call). You can redirect audio to the speaker at the bottom of the phone by using the overrideOutputAudioPort:error: method.

Finally, you can enhance a category to automatically lower the volume of other audio when your audio is playing. This could be used, for example, in an exercise app. Say the user is exercising along to the Music app when your app wants to overlay a verbal message—for instance, “You’ve been rowing for 10 minutes.” To ensure that the message from your app is intelligible, apply the AVAudioSessionCategoryOptionDuckOthers property to your audio session. When ducking takes place, all other audio on the device—apart from phone audio—lowers in volume. Apps that use ducking must manage their session’s activation state. Activate the audio session prior to playing the audio and deactivate the session after playing the audio.

Recording Permission

Starting in iOS 7, your app must ask and receive permission from the user before you can record audio. If the user does not give your app permission to record audio, then only silence is recorded. The system automatically prompts the user for permission when you use a category that supports recording and the app attempts to use an input route.

Instead of waiting for the system to prompt the user for recording permission, you can also use the requestRecordPermission: method to manually ask the user for recording permission. Using the requestRecordPermission: method allows your app to get recording permission from the user at a time that doesn’t interrupt the natural flow of the app. This provides a smoother experience for the user.