为啥 SwiftUI 中的 URL Scheme/onOpenURL 总是打开一个新窗口?

Posted

技术标签:

【中文标题】为啥 SwiftUI 中的 URL Scheme/onOpenURL 总是打开一个新窗口?【英文标题】:Why does URL Scheme/onOpenURL in SwiftUI always open a new window?为什么 SwiftUI 中的 URL Scheme/onOpenURL 总是打开一个新窗口? 【发布时间】:2021-03-15 23:25:52 【问题描述】:

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

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

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

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

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

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

【问题讨论】:

【参考方案1】:

文章"Open window / scene in SwiftUI 2.0 on macOS" 展示了如何打开窗口。我拿走了它的碎片,并把它放到了它可以简单地打开我的窗口而不是另一个窗口的地方。

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

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

preferring 参数是一组字符串,检查它们是否包含在此视图的targetContentIdentifier(本例中为ContentView )中,以查看此视图​​是否更愿意处理外部事件(@ 987654329@ 在这种情况下)与另一个视图。

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

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

参考:Apple Documentation on handlesExternalEvents(preferring:allowing:)

【讨论】:

谢谢!我能够得到这个工作。我最终做了一个匹配:Set(arrayLiteral: "*") for the WindowGroup handlesExternalEvents 这样它就可以接受使用正确的 URL Scheme 发送的任何内容。 我在preferringallowing 上添加了一些信息。如果您有多个视图处理具有相同权限级别的外部事件(通过allowing 设置),我认为preferring 允许一些权重。我不完全清楚为什么你需要两者而不是需要不同的匹配设置字符串,但我只是玩了一下这个来熟悉。

以上是关于为啥 SwiftUI 中的 URL Scheme/onOpenURL 总是打开一个新窗口?的主要内容,如果未能解决你的问题,请参考以下文章

从Android中的HTML页面拨打电话号码时获取net :: ERR_UNKNOWN_URL_SCHEME

SwiftUI开发:解决方法在Xcode中出现“Select a scheme that builds a target which..”

SwiftUI开发:解决方法在Xcode中出现“Select a scheme that builds a target which..”

SwiftUI开发:解决方法在Xcode中出现“Select a scheme that builds a target which..”

Android页面跳转协议_URL Scheme详解

第一次使用Url scheme时App中iOS自定义Url Scheme打不开