Intro to AVAudioSession

Patrick O'Leary
4 min readJul 21, 2017

--

This week, I’m going to talk about a much smaller topic, but one that is close to my heart. I came to iOS development from the audio world, and I always enjoy talking about all things audio in Swift. Today, I’m writing about AVAudioSession.

Take a minute to think about how we use audio in an application. Sometimes we play little blips and bloops to alert the user of something. Other times we’ll have background music for a game or sound from a video. Sometimes sounds can be turned off by the silent switch on the side of your phone. That’s all well and good, but what if we have a clock app, and we need the alarm to override that switch? What if we want our app to keep playing music when the phone’s screen is locked? What happens when our app plays a sound, while another app is playing music?

The way applications handle this is through the use of audio sessions. The first thing to know about audio in an iOS app, is that your app does not directly touch any of the device’s audio hardware. The app communicates to the operating system via an intermediary. This intermediary is an audio session, specifically AVAudioSession. Look! A handy graphic from Apple’s documentation!

When your app is launched, behind the scenes it is provided with a singleton instance of an AVAudioSession. Our app can use the shared instance of AVAudioSession to configure the behavior of audio in the application (First you have to import AVFoundation). To adjust the overall behavior of the AVAudioSession, we can set it to one of several categories. Easily enough, AVAudioSession has a method: setCategory(_:mode:options:). Note that the categories you can set are represented by global String constants, such as “AVAudioSessionCategoryAmbient”

So what do each of these categories do? Well I’m not gonna go over each one of them, so here’s a handy chart for more details. AVAudioSessionCategoryAmbient is the default category. When set to this, audio coming from the app will be turned off by the silent switch, won’t interrupt audio from other applications, and will not accept any audio input. If we set the category to, say, AVAudioSessionCategoryPlayAndRecord, the opposite will be true for each of these.

An important note: if you intend to play audio when the app is in the background, you have to change some settings in your info.plist file. Fortunately, Xcode has an easy way to do this. Just go into your project capabilities, turn on background modes and select “Audio, Airplay, and Picture in Picture.”

Within each AVAudioSession category, there are a number of modes that can be set, which will add further functionality to your session. Again, each of these modes are a String represented by a constant. I wonder if maybe these values are left over from older, Objective-C code, since normally in Swift this would seem like the kind of thing normally represented by an Enum. Anyway, here’s the list for each of these. These modes are smaller performance tweaks that optimize for a certain use case. For example, on devices with more than one microphone, AVAudioSessionModeVideoRecording will turn on the microphone closest to the device’s video camera. It will only work if you’ve set the larger categories, AVAudioSessionCategoryRecord, and AVAudioSessionCategoryPlayAndRecord.

Another important thing to consider is the activation and deactivation of your AVAudioSession, and the error handling in case the activation or deactivation fails. First, here’s an absolutely ridiculous image from the Apple documentation. I swear I’m not making this up:

This is their… explanation… for how AVAudioSession activation works. It’s important to activate and deactivate your audio session at the proper time. If you activate an audio session when it has already been activated, your app will crash. Here’s what all of this together may look like, taken straight from the Apple documentation:

let session = AVAudioSession.sharedInstance()do {// 1) Configure your audio session category, options, and mode// 2) Activate your audio session to enable your custom configurationtry session.setActive(true) //Set to false to deactivate session} catch let error as NSError {print("Unable to activate audio session:  \(error.localizedDescription)")}

So there you have it. Those are the basics of AVAudioSession! All in all, it’s not to hard to understand, at least for your everyday, basic use of audio. There’s one session category, called “AVAudioSessionCategoryMultiRoute” that gets a bit more complicated. This allows you to send different audio streams to different outputs on your device. Unless you’re building an audio mixer app of some kind, I don’t see how you would ever need to use this. Still, it’s a cool thing to at least know that you can do.

That’s all for today! Enjoy your weekend, and as always, leave lots of comments!

--

--