I am encountering an unusual sequence of scene delegate method calls in my Swift iOS app. Specifically, sceneWillEnterForeground gets called before sceneDidEnterBackground, but with a different UIWindowScene instance.
Here's the specific scenario:
Other apps are open and visible in the minimized state in iOS.
I quickly minimize my app and instantly terminate it (swipe up to kill).
In this case, I observe the following sequence of debug prints:
// app launch
sceneWillEnterForeground <UIWindowScene: 0x10270b110>...
sceneDidBecomeActive <UIWindowScene: 0x10270b110>...
// app termination
sceneWillResignActive <UIWindowScene: 0x10270b110>...
sceneDidDisconnect <UIWindowScene: 0x10270b110>...
sceneWillEnterForeground <UIWindowScene: 0x103e06510>...
sceneDidEnterBackground <UIWindowScene: 0x103e06510>...
Notice that sceneWillEnterForeground is called before sceneDidEnterBackground, but with a different UIWindowScene memory address.
However, if I kill the app without other apps visible in the minimized state, or if I do it slowly, I observe the standard sequence of calls without the additional sceneWillEnterForeground:
// app launch
sceneWillEnterForeground <UIWindowScene: 0x106007560>...
sceneDidBecomeActive <UIWindowScene: 0x106007560>...
// app termination
sceneWillResignActive <UIWindowScene: 0x106007560>...
sceneDidDisconnect <UIWindowScene: 0x106007560>...
Why does sceneWillEnterForeground with a new UIWindowScene memory address get called before sceneDidEnterBackground of the previous UIWindowScene memory address in the first scenario? Is this a standard behavior? Can the order of delegate methods vary depending on system behavior and do new UIWindowScene instances get created in such situations?
Any insight into this would be greatly appreciated.
Note that if we use AppDegate, we can encounter the same behavior where applicationWillEnterForeground is called before applicationDidEnterBackground.
Here is a SceneDelegate code so you could quickly reproduce it.
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let _ = (scene as? UIWindowScene) else { return }
}
func sceneDidDisconnect(_ scene: UIScene) {
print("sceneDidDisconnect \(scene)")
}
func sceneDidBecomeActive(_ scene: UIScene) {
print("sceneDidBecomeActive \(scene)")
}
func sceneWillResignActive(_ scene: UIScene) {
print("sceneWillResignActive \(scene)")
}
func sceneWillEnterForeground(_ scene: UIScene) {
print("sceneWillEnterForeground \(scene)")
}
func sceneDidEnterBackground(_ scene: UIScene) {
print("sceneDidEnterBackground \(scene)")
}
}