In my app, I only get one interruption notification when a phone call comes in, and nothing after that. The app uses AVAudioEngine. Is this a bug?
A very simple repro is to just register for the notification, but not do anything else with audio:
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
.onReceive(NotificationCenter.default.publisher(for: AVAudioSession.interruptionNotification)) { event in
handleAudioInterruption(event: event)
}
}
private func handleAudioInterruption(event: Notification) {
print("handleAudioInterruption")
guard let info = event.userInfo,
let typeValue = info[AVAudioSessionInterruptionTypeKey] as? UInt,
let type = AVAudioSession.InterruptionType(rawValue: typeValue) else {
print("missing the stuff")
return
}
if type == .began {
print("interruption began")
} else if type == .ended {
print("interruption ended")
guard let optionsValue = info[AVAudioSessionInterruptionOptionKey] as? UInt else { return }
if AVAudioSession.InterruptionOptions(rawValue: optionsValue).contains(.shouldResume) {
print("should resume")
}
}
}
}
And do this in the app's init:
@main
struct InterruptionsApp: App {
init() {
try! AVAudioSession.sharedInstance().setCategory(.playback,
options: [])
try! AVAudioSession.sharedInstance().setActive(true)
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
Please see the Responding to Interruptions section of the Audio Session Programming Guide. In general, there is no guarantee that a begin interruption will have a corresponding end interruption. Regarding phone calls, if the user ignores the incoming call, the system posts a notification indicating that the interruption has ended. However, if the user accepts the phone call, your app is suspended.