I\'m finding it extraordinarily difficult to categorize and account for what events I get (or don\'t get) when the user swipes my app up in the app switcher on iOS 13. This
in my case, I want to save user state when the app is terminated by the user or the system, applicationWillTerminate(_:)
does not being called for me most of the time.
I achieved what I want by using sceneWillResignActive(_ scene: UIScene)
Let's assume that your app supports window scenes. So what the user is swiping up in the app switcher is really a scene, not your app as a whole. Then the possibilities appear to be as follows.
If the scene was frontmost:
sceneDidEnterBackground
applicationWillTerminate(_:)
But if the scene was not frontmost, you'll get nothing; you already received sceneDidEnterBackground
, and you won't get applicationWillTerminate(_:)
now because the app isn't running.
If the scene was frontmost:
sceneDidDisconnect(_:)
application(_:didDiscardSceneSessions:)
applicationWillTerminate(_:)
But if the scene was not frontmost, you'll get nothing; you already received sceneDidEnterBackground
, and you won't get applicationWillTerminate(_:)
now because the app isn't running.
If the scene was frontmost:
sceneDidEnterBackground
applicationWillTerminate(_:)
(perhaps)But if the scene was not frontmost, you'll get nothing; you already received sceneDidEnterBackground
, and you won't get applicationWillTerminate(_:)
now because either the app isn't running or the app isn't terminating (if there's another window). If the app is still running, you might get sceneDidDisconnect(_:)
and possibly application(_:didDiscardSceneSessions:)
later.
What's the odd-man-out here? It's the case where we're running on an iPad and we support scenes but not multiple windows. We don't get sceneDidEnterBackground
! I regard that as incoherent. Since we don't support multiple windows, this is basically an iPhone app and it should behave like an iPhone app. I shouldn't have to double up my code just because my app runs on both iPhone and iPad.