使用 SwiftUI Lifecycle 在 iOS 应用上启动新的 window

Launch new window on iOS app using SwiftUI Lifecycle

WindowScene 上的以下代码确实会在 ContentView 中按下打开 URL 的按钮时在 macOS 上打开一个新的 window:

import SwiftUI

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    
        WindowGroup("Viewer") {
            Text("Viewer").padding()
        }
        .handlesExternalEvents(matching: ["*"])
    }
}

但是,当同样应用于 iOS 时,应用程序在调用 openURL 操作时不执行任何操作。

我研究的结果是,我可以使用传统的requestSceneSessionActivation手动打开window。但是,这将破坏使用 SwiftUI 应用程序生命周期的目的。

在不返回 UIKit 生命周期的情况下,对工作方法有什么建议吗?

经过很长时间的研究,我终于在 this blog post 中找到了执行此操作的 属性。

事实证明 requestSceneSessionActivation 是必需的,但没有必要使用 SceneDelegate

创建新会话时,在 NSUserActivity 对象上设置 targetContentIdentifier

let activity = NSUserActivity(activityType: "newWindow")
activity.userInfo = ["some key":"some value"]
activity.targetContentIdentifier = "newWindow" // IMPORTANT
UIApplication.shared.requestSceneSessionActivation(nil, userActivity: activity, options: nil)

最后,确保新的WindowGroup可以处理带有标识符的事件:

WindowGroup(id: "newWindow") {
    Text("New Window!").padding()
}
.handlesExternalEvents(matching: ["newWindow"])

此解决方案保留了 SwiftUI 生命周期,也适用于 Catalyst。