Broken FaceTime Audio Interruptions in iOS 9

Constant Interruptions

I’ve been working on a new feature for RabbleTV the past 3 months. Now that the functionality is pretty close to shipping I’m going through all the various testing scenarios of making sure that if/when the user gets an audio interruption (phone call, FaceTime, etc) that I handle the app state appropriately.

Apple has pretty straight forward guidelines of how to handle these types of interruptions. When one occurs the AVAudioSessionInterruptionNotification is sent out and the developer can inspect whether the AVAudioSessionInterruptionTypeKey is equal to AVAudioSessionInterruptionTypeBegan or AVAudioSessionInterruptionTypeEnded and handle their app state and UI appropriately.

HOWEVER, looking closer at the documentation there is one very important sentence:

There is no guarantee that a begin interruption will have an end interruption. Your app needs to be aware of switching to a foreground running state or the user pressing a play button. In either case, determine whether your app should reactivate its audio session.

Cause for Panic?

Receiving FaceTime calls on iOS 8 works “as expected”. The appropriate notifications are fired off by iOS and I’m able to pause and continue my use of the microphone. The development was moving right along until I started testing under iOS 9.

Going through the same scenario using iOS 9 the AVAudioSessionInterruptionTypeEnded type is never available. The AVAudioSessionInterruptionNotification is called when the interruption begins and ends, but the only type that is set is AVAudioSessionInterruptionTypeBegan.

iOS 9 Log

2015–09–17 09:40:32.098 RabbleTV[6541:2258301] _66-[RTVBroadcastingManager addAudioInterruptionNotificationListener]block_invoke(271): notification for interruption NSConcreteNotification 0x14e8a6ea0 {name = AVAudioSessionInterruptionNotification; object = <AVAudioSession: 0x14e813220>; userInfo = { AVAudioSessionInterruptionTypeKey = 1;}}

iOS 8 Log

2015–09–17 09:34:35.405 RabbleTV[471:106341] _66-[RTVBroadcastingManager addAudioInterruptionNotificationListener]block_invoke(271): notification for interruption NSConcreteNotification 0x17f31ab0 {name = AVAudioSessionInterruptionNotification; object = <AVAudioSession: 0x17ee4860>; userInfo = { AVAudioSessionInterruptionTypeKey = 1;}} 2015–09–17 09:34:52.715 RabbleTV[471:106341] _66-[RTVBroadcastingManager addAudioInterruptionNotificationListener]block_invoke(271): notification for interruption NSConcreteNotification 0x17dae300 {name = AVAudioSessionInterruptionNotification; object = <AVAudioSession: 0x17ee4860>; userInfo = { AVAudioSessionInterruptionOptionKey = 1; AVAudioSessionInterruptionTypeKey = 0; }}

I have some business rules that add a bit more complexity to work around this issue, but if your only concern is to know when it the interruption began and ended then you can set a property to toggle between the states.

I’ve filed a radar with Apple.