WWDC2020 videos said SwiftUI on Xcode12 can create and manage different scenes in an App, but we do not find out any API could do that. We try the method of SwiftUI on Xcode11 to create new Window on Xcode 12 :
UIApplication.shared.requestSceneSessionActivation(nil, userActivity: nil, options: nil, errorHandler: nil) })
But it does not work as we expect. The code create a window of the same scene. If we set a different userActivity, SwiftUI have no method to set SceneDelegate.swift. It only has @UIApplicationDelegateAdaptor to set AppDelegate.
So, I Wonder whether there is a convenient way to create a new Scene by new SwiftUI APIs.
The following code can only create Scenes with the same content view :
UIApplication.shared.requestSceneSessionActivation(nil, userActivity: nil, options: nil, errorHandler: nil) })
But it does not work as we expect. The code create a window of the same scene. If we set a different userActivity, SwiftUI have no method to set SceneDelegate.swift. It only has @UIApplicationDelegateAdaptor to set AppDelegate.
So, I Wonder whether there is a convenient way to create a new Scene by new SwiftUI APIs.
The following code can only create Scenes with the same content view :
Code Block @main struct test: App { let newWindowPublisher = NotificationCenter.default.publisher(for: Notification.Name("anotherScene")) var body: some Scene { WindowGroup { ContentView() .onReceive(newWindowPublish, perform: { info in UIApplication.shared.requestSceneSessionActivation(nil, userActivity: nil, options: nil, errorHandler: nil) }) } } }
Code Block @main struct mindoApp: App { @UIApplicationDelegateAdaptor private var appDelegate: AppDelegate var body: some Scene { WindowGroup { ContentView() } } } class AppDelegate: NSObject, UIApplicationDelegate { func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { if options.userActivities.first?.activityType == "newWindow" { let configuration = UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) configuration.delegateClass = SceneDelegate.self return configuration } else { return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) } } class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { if let windowScene = scene as? UIWindowScene { let window = UIWindow(windowScene: windowScene) window.rootViewController = UIHostingController(rootView: TestView()) self.window = window window.makeKeyAndVisible() } } }
The following code is used to create a new scene/window
Code Block UIApplication.shared.requestSceneSessionActivation(nil, userActivity: NSUserActivity(activityType: “newWindow"), options: nil, errorHandler: nil)
The TestView can be put into the second scene/window on iPadOS/macOS. But, the App crashes when closing the second scene/window:
Fatal error: Attempted to read an unowned reference but object 0x60000061d1c0 was already deallocated