Multi-window support and state restoration on iOS/iPadOS
Implementing state restoration is a great way to improve an app’s usability and multiple window support allows user to be more productive when using iPad apps. Adding these technologies requires a new way of thinking about the application lifecycle in order to deliver a great user experience.
The most basic type of multi window support on iPadOS enables users to have an app side by side with another one (1st or 3rd party apps). More advance multi window support involves displaying two screens of the same app side by side.
Let’s look at how to leverage these technologies to improve the user's experience before deciding whether or not to invest in supporting those features.
Should our app support multiple windows on iPad?
First thing you should keep in mind is that the user should be able to use all your app’s features in one window. If you need multiple window for your app to function then you are thinking about it the wrong way. With that said depending on the type of app your team is building it might really be worth it for your users to use multiple windows.
Different Apps Side by Side: If you see value in your users being able to open other apps (mail, files or map etc.) next to your app then it makes sense to add basic multi window functionality. Your users will be able browse the web in safari for example and use your app at the same time on an iPad.
Same App Side by Side: If your app has multiple tab views which represent different logical sections it might be worth it to allow users to open these tabs in separate windows. In my experience, tab views are the only type of views that make sense in a separate window because they are by design a distinct section of your app. An app that has only one tab view but multiple sub-views that are connected by a navigation bar would not be a good candidate for multi-window support. Allowing users to open navigation views/screens in a separate window doesn’t provide a great user experience.
How do I determine if our app needs to support state restoration?
To determine if you app needs to support state restoration ask yourself what would you want your users to see when they launch your app. If your app has multiple screens and the user navigate to a nested view and then they close the app, due to resource constraints the system may disregards your app’s state in memory. When the user reopens the app, does it make sense to display the app’s landing screen or should it display the last screen the user was on before closing the app? If it makes sense for the user to be taken right were they left off after closing your app then it should support state restoration.
How will our users manage the experience of using multiple windows?
You should think of windows as being either universal or dedicated.
Universal Windows are basically clones of your whole app. Users can navigate through the whole app in one window.
Dedicated Windows display specific screens or sections of your app and does not allow for navigation through the whole app.
If you allow the user to open any view in a separate window it can easily become overwhelming to manage it all. Even in cases where universal windows are appropriate you should still think about limiting how many windows with the same view that can be opened since currently on iPad users are limited to a max of 2 windows side by side or overlaid on top of each other.
Window management is partially handled by Apple since the user can delete windows by swiping up. The way you can help users manage windows in your app is by controlling how they are created by placing some restrictions when appropriate.
How deep in a navigation view hierarchy should we apply state restoration?
In most cases you should go as deep as the user navigated before they closed the app. In most cases you should bring the user exactly back to the screen they were on, scrolled to the exact vertical position and if they were in the middle of typing something the keyboard should appear.
I say in most cases and not always because sometimes you might want to give the user the ability to “reset” the app. When the user explicitly wants see your app's landing view, state restoration should not be applied. A good way to tell is if the user deletes a window scene by swiping up in the app switcher. In this case the user should be brought back to the app's landing view but if the scene was deleted by the system because of resource constraint then state restoration should be applied.
Does implementing multi-window support change my current workflow?
Multi-window support does bring some changes to your current workflow. UIApplication and UIApplicationDelegate no longer handles UI state, events or life cycle. That responsibility is now handled by UIWindowScene and UIWindowSceneDelegate.
How do I implement multi-window support in code?
UIWindowScene. This object manages the life cycle of a single instance of your app’s UI as well as all the windows displayed by that scene. When the state of your scene changes, the UIWindowScene instance notifies its delegate object (UIWindowSceneDelegate) and you can write code to react to new and removed scenes. You do not need to create window scene objects directly. Instead, specify that you want a UIWindowScene object at configuration time by including a class name for the scene in your app's Info.plist file.
UISceneSession. This object managers a unique instance of your scene in order to track that scene when the user adds a new scene to your app or when you request one programatically. The session contains a unique identifier as well as the configuration details for that scene. You do not need to create session objects directly. UIKit creates sessions for you in response to user interactions. You can also ask UIKit to create a a new scene and session programmatically by calling the requestSceneSessionActivation(_:userActivity:options:errorHandler:) method of UIApplication.
NSUserActivity. This object provides a quick way to capture the state of your app and put it to use later. You create user activity objects and use them to capture information about what the user was doing. When the system launches your app and an activity object is available, your app can use the information in that object to restore itself to an appropriate state.