为什么SwiftUI中的URLScheme/onOpenURL总是打开一个新窗口?

Sim*_*mon 18 macos swiftui

我正在将旧的 macOS 应用程序转换为 SwiftUI,但在使用新的 SwiftUI WindowGroup 时遇到了问题。

旧的应用程序是一个单窗口应用程序(基本上是一个美化的计时器),并且可以使用 URL 方案(appname://15)来更改计时器。

我尝试使用 onOpenURL 方法重新创建旧的 URL 方案功能,但每当触发 URL 方案时,应用程序都会打开一个新窗口,并且我不知道如何阻止这种情况发生。

var body: some Scene {
        WindowGroup {
            ContentView()
                .onOpenURL(perform: { url in
                    print("\(url)") // This is just debug code
                })
        }.commands {
            CommandGroup(replacing: .newItem, addition: { })
        }
    }
Run Code Online (Sandbox Code Playgroud)

我不介意新版本的应用程序是否允许多个计时器,但 url 方案绝对不是为了每次使用时都打开新窗口。

如何阻止 onOpenURL 启动新窗口?我专门转换应用程序来学习 SwiftUI,但如果无法在 SwiftUI 中执行此行为,我愿意在一些 AppKit 代码中进行混合和匹配。

Mr *_*ers 21

文章“在 macOS 上的 SwiftUI 2.0 中打开窗口/场景”展示了如何打开窗口。我把它的碎片放到了它会打开我的窗户而不是另一扇窗户的地方。

var body: some Scene {
 WindowGroup {
   ContentView()
     .handlesExternalEvents(preferring: ["{path of URL?}"], allowing: ["*"]) // activate existing window if exists
     .onOpenURL(perform: { url in
         print("\(url)") // This is just debug code
      })
   }.commands {
      CommandGroup(replacing: .newItem, addition: { })
   }
   .handlesExternalEvents(matching: ["{same path of URL?}"]) // create new window if doesn't exist
}
Run Code Online (Sandbox Code Playgroud)

对于那些想要(尝试)更好地理解preferringallowing参数的人。摘自苹果文档:

preferring参数是一组字符串,检查它们是否包含在targetContentIdentifier该视图(ContentView 在本例中)中,以查看该视图相对于另一个视图是否更喜欢处理外部事件(openURL在本例中)。

allowing参数是一组字符串,检查它们是否包含在targetContentIdentifier此视图中,从而允许视图处理事件。

空集永远不会匹配。"*"总是匹配的。

参考:关于handlesExternalEvents的Apple文档(preferring:allowing:)

  • 谢谢!我能够让这个工作。我最终为 WindowGroup handlesExternalEvents 做了匹配: Set(arrayLiteral: "*") ,以便它接受使用正确的 URL 方案发送的任何内容。 (2认同)