Understanding Scene Delegate & App Delegate
Earlier to Xcode 11, when a new project is created you know that some default files like AppDelegate.swift, ViewController.swift and a StoryBoard and few other files are created. But from Xcode 11 you might have noticed that along with the default files like above, a new file is created named as SceneDelegate.swift.
This new file might be pretty confusing for you to understand what it is, why it is created and how to use that scene delegate in your application development. Let’s try to understand the difference betweend AppDelegate and SceneDelegate.
In all the apps built prior iOS 13, AppDelegate is the main entry of the app and it is the place where many logics and app states will be handled. It is the place where application launch and apps foreground and background logics are handled. From iOS 13, the responsibilites of AppDelegate have been split between AppDelegate and SceneDelegate. This is the result of new multi-window support feature that is introduced with iPad-OS and that splits the work of AppDelegate into two.
The AppDelegate will be responsible for the application lifecycle and setup. The SceneDelegate will be responsible for what is shown on the screen (Windows or Scenes) handle and manage the way your app is shown.
AppDelegate and Scene Delegate responsibilities
Even in iOS 13, the AppDelegate is still the main point of entry for an application. AppDelegate methods are called for application level lifecycle events. In the default AppDelegate.swift there are three methods that Apple considers to be important that we have to consider and let’s look into them:
1. func application(_:didFinishLaunchingWithOptions:) -> Bool
2. func application(_:configurationForConnecting:options:) -> UISceneConfiguration
3. func application(_:didDiscardSceneSessions:)
- func application(_:didFinishLaunchingWithOptions:) -> Bool
This method is called when the application is launched and where the application set-up is done. Earlier iOS 13, we might have used this method to configure the UIWindow object and assign a ViewController instance to the UIWindow object to make it display on the screen. From iOS 13, if your application has scenes, then AppDelegate is no longer responsible for handling this and is moved to SceneDelegate.
- func application(_:configurationForConnecting:options:) -> UISceneConfiguration
This method is called when ever the application needs a new scene or window to display. This method is not called on app launch but only when a new scene or a new window is need to be obtained.
- func application(_:didDiscardSceneSessions:)
This method is called when ever user discards a scene like by swiping it from the multitasking window or if discarded programatically. This method is called for every discarded scene shortly after the (_:didFinishLaunchingwithOptions:) method is called if the app isn’t running when user discards the scene.
Inaddition to these methods, AppDelegate can still handle the external services like push notification registrations, location services, app termination and more.
From iOS 13 and later, SceneDelegate takes up some responsibilites from AppDelegate. In particular related to UIWindow from AppDelegate is now UIScene in SceneDelegate. An app can have more than one scene which mostly handles application interface and app content. So, the SceneDelegate is responsible for what’s displayed on the screen in terma of UI and data.
The default methods that can be seen in SceneDelegate are
These methods sounds similar to the methods that we had worked in AppDelegate in iOS 12 and earlier. You will be able to understand what each method is meant for by looking into the names but the only difference is the terminology.
This is the first method called in UISceneSession life cycle. This method will creates new UIWindow, sets the root view controller and makes this window the key window to be displayed.
This method is called when the scene is about to start like when app becomes active for the first time or when transitions from background to foreground.
This method is called right after the WillEnterForeground method and here the scene is set-up and visible and ready to use.
- sceneWillResignActive(_:) and sceneDidEnterBackground(_:)
These methods are called when app stages to backgground .
This is the interesting method of all the methods. When ever the scene is sent to background, iOS might decide to completely discard the scene to free up the resources. This doesn’t meant that the app is killed or not running, but just the scene is disconnected from the session and is not active. iOS can decide to reconnect back this scene to scene session when the user brings that particular scene to foreground again . This method can be used to discard any resources that aren’t used anymore.
The main reason for Apple to add UISceneDelegate to iOS 13 was to create a good entry point for multi-windowed applications. By the above theory you might have understood the roles of AppDelegate and SceneDelegate in iOS 13 and their life cycle events. AppDelegate is responsible for handling application-level events, like app launch and the SceneDelegate is responsible for scene lifecycle events like scene creation, destruction and state restoration of a UISceneSession.