The step " Resources Reclaimed " is actually a key to understanding how iOS works.
→ Resources like CPU time or memory are limited, and the OS always has to decide how to allocate these resources.
So how does iOS decide what to prioritize?
A. It prioritizes whichever app is running in the foreground , because that's obviously what the user is looking at.
But think about a situation, for example, when a user just wrote an entire registration form, and went back to the Home Screen.
→ You uses will lose all of their progress and all their data, unless you've already saved the app's data
Q. But how would you know at which time point to save your user's data?
A. You should do it at the point in the lifecycle when your app is going into the background.
→ Upon leaving the foreground-active state, save data and quiet your app's behavior.
Q. So where can we find these app lifecycle methods?
A. They all live in the AppDelegate.swift and SceneDelegate.swift files that are created automatically when you make a new Xcode project.
note: Before iOS 12, all the app lifecycle methods were in AppDelegate.swift
→ But after iOS 13 (along with iPad OS), apps can now run in multiple windows.
→ This means that there can be multiple windows running different instances of your app.
→ In other words, there are 2 separates "scenes" ⇒ Why we get SceneDelegate.swift
ex. If one of the windows goes into the background, the the SceneDelegate for that windows gets notified.
SceneDelegate treats each of these windows being open as a separate scene.
Events that are common to the app are handled in the AppDelegate.
All other lifecycle callbacks are in the SceneDelegate.
Q. What are handled by the AppDelegate?
A. Things like being launched or receiving a time change from the network carrier.
Q. Then what does the SceneDelegate handle?
A. Things like window becoming visible or going into the background. (similar to a ViewController)
→ Each of these have lifecycle methods you can override.
ex. What can we override in AppDelegate?
// AppDelegate.swif
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}
→ Here, we can configure things as soon as the app launches
ex) Firebase.configure( )
ex. What can we override in SceneDelegate?
// SceneDelegate.swift
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
ex) If we receive a phone call → It's a good idea to put some code in here to deal with any of these temporary interruptions.
ex) If we get a phone call when we are listening to music in Spotify, it's recommended to maybe pause the music, or turn the volume down.
// SceneDelegate.swift
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
→ This is the moment where you app goes from the foreground to the background.
Important : This is a really good time to save a user's data.
→ Save what a user typed in.
Why save?
A. Because the next time point where the app actually gets "destroyed" can be unpredictable.
You never know when you app is going to be deallocated from the RAM. Your app might actually get killed silently if a user suddenly decides to run, for example, a RAM-hungry 3D game.
// SceneDelegate.swift
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
→ Here, we can use the data saved previously to "repopulate" any of the fields that might be empty.