SceneDelegate in Swift: From Basics to Mastering Multitasking

Advanced Techniques for Scene Interaction and State Restoration

Vikram Kumar
8 min readOct 23, 2023

Introduction

In the ever-evolving world of iOS app development, the introduction of SceneDelegate in Swift marked a significant shift in how apps manage their user interfaces and interactions. SceneDelegate brings with it the power to handle multiple windows, empowering developers to build more efficient and user-friendly applications. With its introduction in iOS 13 and subsequent versions, mastering the intricacies of SceneDelegate has become essential for modern iOS developers.

In this article, we will explore the ins and outs of SceneDelegate, from its fundamental concepts to advanced techniques, complete with real-world coding examples. Whether you’re new to iOS development or an experienced developer looking to harness the full potential of SceneDelegate, this article will equip you with the knowledge and skills needed to create seamless, multitasking iOS applications.

Let’s embark on a journey to demystify SceneDelegate, unlocking its potential to manage app scenes, handle state restoration, facilitate inter-scene communication, and take advantage of the iPadOS multi-window experience. By the end of this guide, you’ll be well-versed in the art of SceneDelegate and ready to apply its capabilities to build robust, user-friendly apps.

Photo by Sean Oulashin on Unsplash

Understanding SceneDelegate

The SceneDelegate was introduced in iOS 13 to replace the AppDelegate’s role in managing app scenes. A scene can be thought of as a user interface with its own lifecycle and states, and the SceneDelegate is responsible for handling these scenes. It allows for more efficient multitasking on iOS devices.

What is Scene?

In the context of the SceneDelegate in iOS app development, a “scene” refers to a distinct user interface or window within your application. It represents a particular instance of your app’s user interface that the user interacts with.

Scenes allow users to work with different parts or views of your app simultaneously, promoting multitasking and enhancing the user experience.

Each scene can have its own lifecycle, state, and interaction with the user. For example, in a messaging app, each chat conversation might be represented as a separate scene. In a document editing app, different sections of the document could be separate scenes.

The introduction of scenes in iOS was a significant step toward enabling more efficient multitasking on devices, particularly on iPad and in multi-window environments. SceneDelegate is responsible for managing these scenes, determining how they are created, activated, deactivated, and terminated, and handling state restoration when a user switches between scenes.

In summary, a “scene” in SceneDelegate represents a self-contained unit of the user interface in your app, and SceneDelegate’s role is to manage the various scenes and their lifecycles.

import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }

// Create a new window and set the root view controller
let viewController = ViewController()
window = UIWindow(windowScene: windowScene)
window?.rootViewController = viewController
window?.makeKeyAndVisible()
}
}

Key Methods and Responsibilities

Scene Activation

sceneWillConnectToSession(_:options:)

This method is called when a new scene is created or brought to the foreground. It provides an opportunity to set up the scene’s initial state.

Example: Imagine you’re developing a social networking app where users can share moments through photos. When a user taps on a notification to view a new photo shared by a friend, this method can be used to initialize the scene and set up the UI to display the photo.

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
if let photoURL = connectionOptions.urlContexts.first?.url {
let photoViewController = PhotoViewController(photoURL: photoURL)
window?.rootViewController = photoViewController
}
}

sceneDidBecomeActive(_:)

This method is called when a scene becomes active, meaning the user is interacting with it.

Example: Consider an e-commerce app where users can make purchases. When a user is in the middle of a purchase and switches to a different app, this method can be used to resume the payment process and re-enable user interaction when the app becomes active again.

func sceneDidBecomeActive(_ scene: UIScene) {
if let paymentInProgress = PaymentManager.shared.checkPaymentStatus() {
// Resume the payment process
PaymentManager.shared.continuePayment(paymentInProgress)
}
}

Scene Deactivation

sceneWillResignActive(_:)

Called when a scene is about to resign its active state, such as when it enters the background.

Example: In a navigation app, when a user receives a phone call while using the app for directions, this method can be used to pause navigation and save the current location to resume it when the app becomes active again.

func sceneWillResignActive(_ scene: UIScene) {
if NavigationManager.shared.isNavigating {
NavigationManager.shared.pauseNavigation()
LocationManager.shared.saveCurrentLocation()
}
}

sceneWillEnterForeground(_:)

Called when a scene is about to re-enter the foreground.

Example: Consider a news app where users can read articles. When a user switches back to the app from the background, this method can be used to refresh the list of articles and update the UI.

func sceneWillEnterForeground(_ scene: UIScene) {
ArticleManager.shared.fetchLatestArticles { articles in
if let articles = articles {
ArticleListViewController.shared.updateUI(with: articles)
}
}
}

Scene Termination

sceneWillDisconnect(_:)

This method is called when a scene is about to be removed or disconnected.

Example: In a document editing app, when a user closes a document view, this method can be used to save any unsaved changes and release resources associated with that document scene.

func sceneWillDisconnect(_ scene: UIScene) {
if DocumentManager.shared.hasUnsavedChanges {
DocumentManager.shared.saveDocument()
}
DocumentManager.shared.releaseResourcesForScene(scene)
}

Working with Multiple Scenes

Working with Multiple Scenes in SceneDelegate is essential for apps that want to make the most of multitasking capabilities.

Creating Additional Scenes

Example: Imagine you’re building a collaborative document editing app where users can work on multiple documents simultaneously. When a user wants to open a new document, you can create a new scene for it.

func createNewDocumentScene(document: Document) {
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else { return }

let documentViewController = DocumentViewController(document: document)
let newDocumentScene = UIWindowScene(sessionRole: .windowApplication)

// Set up the window and its root view controller
let window = UIWindow(windowScene: newDocumentScene)
window.rootViewController = documentViewController
window.makeKeyAndVisible()
}

In this example, a new scene is created for each document, allowing users to work on multiple documents concurrently.

Handling State Restoration

Example: In a note-taking app, you want users to be able to switch between their notes without losing their current work. Scene restoration is vital in this scenario.

func scene(_ scene: UIScene, willEnterForegroundWithSession session: UISceneSession) {
// Check if the scene has a restoration identifier
if let restorationIdentifier = scene.session.persistentIdentifier {
if let note = NoteManager.loadNoteFromStorage(withIdentifier: restorationIdentifier) {
// Restore the note's content in the scene
if let viewController = (window?.rootViewController as? NoteViewController) {
viewController.loadNoteContent(note.content)
}
}
}
}

In this example, when a scene enters the foreground, the SceneDelegate checks if it has a restoration identifier and restores the note’s content if available.

Advanced SceneDelegate Techniques

Advanced SceneDelegate techniques are crucial for building versatile and feature-rich iOS applications.

Inter-Scene Communication

Let’s consider a scenario where we have multiple scenes in a collaborative document editing app. Each scene represents a different section of the document. We need a way for scenes to communicate and synchronize their content.

// In Scene A
func shareContent(withScene sceneB: UIScene) {
if let sceneBDelegate = (sceneB.delegate as? SceneDelegate) {
sceneBDelegate.updateContent(content)
}
}

// In Scene B
func updateContent(_ content: String) {
// Update the content in Scene B
}

In this example, Scene A can call the updateContent method in Scene B to synchronize content.

SceneDelegate for iPadOS

When designing apps for iPadOS, you can take advantage of multiple windows. In a note-taking app, you can use SceneDelegate to manage multiple note windows.

func createNewNoteScene() {
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene else { return }

let newNoteScene = UIWindowScene(sessionRole: .windowApplication)
let newNoteViewController = NoteViewController()

// Customize the appearance for the new window
newNoteScene.sizeRestrictions?.minimumSize = CGSize(width: 320, height: 480)
newNoteScene.sizeRestrictions?.maximumSize = CGSize(width: 600, height: 800)

newNoteScene.title = "New Note"

newNoteScene.delegate = NoteSceneDelegate(viewController: newNoteViewController)

UIApplication.shared.requestSceneSessionActivation(nil, userActivity: nil, options: nil, errorHandler: nil)
}

In this example, we create a new window scene for a note and specify a custom delegate, NoteSceneDelegate, for that scene.

These advanced SceneDelegate techniques demonstrate how to harness the full potential of SceneDelegate for building dynamic, interactive, and versatile iOS applications. Whether it’s facilitating real-time collaboration between scenes or adapting your app for the unique features of iPadOS, SceneDelegate empowers you to create engaging and efficient user experiences.

SceneDelegate Best Practices

Best practices for working with SceneDelegate in your iOS app are essential to ensure a smooth and responsive user experience.

1. Effective Scene Management: Manage scenes efficiently to optimize multitasking capabilities, allowing users to work on different tasks in parallel.

2. State Restoration: Implement state restoration to provide a seamless experience when users switch between scenes, preserving their app’s state.

3. Inter-Scene Communication: Facilitate communication between scenes when they need to collaborate or share data, enabling real-time synchronization.

4. Adaptation for iPadOS: Tailor your app’s behavior for iPadOS, taking advantage of multi-window capabilities for a more versatile user experience.

5. Optimized Resource Management: Efficiently manage resources in each scene to ensure smooth performance and responsiveness.

6. Error Handling: Implement robust error handling to gracefully manage unexpected situations during scene management, enhancing the app’s reliability.

7. User Interface Consistency: Maintain a consistent user interface experience across scenes to ensure a seamless transition for users as they switch between different parts of the app.

By adhering to these best practices, developers can create apps that provide a responsive, multitasking-ready, and user-friendly experience, adapting to various devices and user scenarios.

Interview Questions:

Most asked interview questions related to Swift SceneDelegate:

  1. What is SceneDelegate in iOS, and when was it introduced?
  2. How does SceneDelegate differ from AppDelegate in terms of responsibilities and scope?
  3. Explain the key methods in SceneDelegate and their roles in managing app scenes.
  4. Why is state restoration important, and how does SceneDelegate handle it? Provide a real-world scenario where state restoration is beneficial.
  5. In a multitasking context, what is the significance of the `scene(_:, willConnectTo: options:)` method? Can you give an example of its use in an app?
  6. How can you create a new scene in SceneDelegate, and why might you need to do this in an app?
  7. What are some real-world scenarios where facilitating communication between scenes is essential, and how can SceneDelegate help achieve this?
  8. Explain the role of SceneDelegate in managing scene termination. Why is it important to manage scene termination effectively in iOS apps?
  9. In what context is SceneDelegate important for iPadOS apps, and what benefits does it offer in a multi-window environment?
  10. How can SceneDelegate be used to optimize resource management for better app performance? Provide an example where efficient resource management in SceneDelegate is crucial.

Conclusion

Mastering the Swift SceneDelegate is crucial for creating modern, multitasking iOS apps. Understanding its methods and responsibilities, working with multiple scenes, and implementing advanced techniques are key to developing robust, user-friendly applications. By following best practices, you can harness the full potential of SceneDelegate and provide a seamless user experience in your apps.

Happy Coding!!!

--

--

Vikram Kumar
Vikram Kumar

Written by Vikram Kumar

I am Vikram, a Senior iOS Developer at Matellio Inc. focused on writing clean and efficient code. Complex problem-solver with an analytical and driven mindset.

No responses yet