Reputation: 203
I'm working on an AudioKit app, and have run into an issue with managing the app lifecycle. When I receive an incoming FaceTime call, I would like to be able to update my app state so it can recover properly when the call ends and my app is in the foreground again.
When a call is received and the notification appears, my app's audio stops immediately, which is fine.
If the incoming call is accepted, both sceneWillResignActive and sceneDidEnterBackground are called, and I can respond appropriately.
If the incoming call is rejected, or cancelled by the caller before being accepted, even though the audio has stopped, no scene delegates are called, so I am not able to properly update my app state.
I can demonstrate this behaviour by just logging the scene delegate calls in a brand new Swift Storyboard App project. Obviously there is no audio but I can see which delegates are called when a call comes in. And in my testing, if a call is rejected, no delegates are called.
So my question is if there is a way for my app to know about an incoming call, other than the functions in SceneDelegate.
Testing with iPhone 14 Pro / iOS 16.3.1 and iPad Pro (3rd Generation) / iPadOS 16.3.1. I have only tested calling into the device with FaceTime.
To watch the scene delegate calls:
Create a new Swift App Storyboard project, and replace contents of SceneDelegate with the following. Run the app on a physical device, call in to the device from another device using FaceTime, and watch the Xcode debug console. Try accepting and rejecting the FaceTime calls to see the difference.
import UIKit
import os
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
let lifecycle = Logger(subsystem: "com.myComany.lifecycletest", category: "lifecycle")
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
lifecycle.log("scene willConnectTo")
guard let _ = (scene as? UIWindowScene) else { return }
}
func sceneDidDisconnect(_ scene: UIScene) {
lifecycle.log("sceneDidDisconnect")
}
func sceneDidBecomeActive(_ scene: UIScene) {
lifecycle.log("sceneDidBecomeActive")
}
func sceneWillResignActive(_ scene: UIScene) {
lifecycle.log("sceneWillResignActive")
}
func sceneWillEnterForeground(_ scene: UIScene) {
lifecycle.log("sceneWillEnterForeground")
}
func sceneDidEnterBackground(_ scene: UIScene) {
lifecycle.log("sceneDidEnterBackground")
}
}
Upvotes: 1
Views: 435
Reputation: 203
Turns out that the answer to my question is yes:
"Is there a way for my app to know about an incoming call, other than the functions in SceneDelegate."
Everything I needed is here - Use the Notification Center to observe and respond to interruptions. The provided sample code works great!
Responding to Audio Session Interruptions
Upvotes: 2