带有“App”协议深度链接的 SwiftUI macOS 应用程序打开了新的应用程序实例

Posted

技术标签:

【中文标题】带有“App”协议深度链接的 SwiftUI macOS 应用程序打开了新的应用程序实例【英文标题】:SwiftUI macOS app with `App` protocol deep linking opens new app instance 【发布时间】:2020-11-23 09:12:47 【问题描述】:

这是在 SwiftUI macOS 应用程序中使用新的 App 协议和 @main

使用流程:

用户启动应用程序并单击打开特定网页的按钮 网页最终重定向到应用程序的 URL 方案,打开应用程序并调用 onOpenURL(_:)

预期行为: 深层链接被发送到现有的、当前打开的应用实例

实际行为: 启动了一个新的应用实例,导致该应用的两个实例处于活动状态

注意:实际上不需要添加任何代码,因为问题只是依赖于向应用添加 URL 方案并让网页访问它。

【问题讨论】:

不可能在 macOS 上运行应用程序的两个实例,除非您安装了应用程序的多个副本(例如,一个在 Applications 中,另一个在 Xcode 的构建目录中)。如果您同时运行这两个应用程序,请尝试右键单击每个应用程序并选择“在查找器中显示”,这将显示应用程序所在的位置。如果安装了第二个应用,请将其删除。 【参考方案1】:

onOpenURL(_:) 实际上并没有启动一个新的应用程序实例,它是在现有实例中创建一个新窗口。文档表明这只发生在 macOS 上(因为 ios 只支持单个窗口)。

您需要在高阶视图上使用.handlesExternalEvents(preferring:allowing:) 修饰符。调用 handlesExternalEvents 将覆盖默认行为,即在 macOS 上的应用程序中创建新窗口。比如:

@main
struct myApp: App     
    var body: some Scene 
        WindowGroup 
            ContentView()
            .handlesExternalEvents(preferring: ["myscheme"], allowing: ["myscheme"])
        
    

然后在子视图中(例如ContentView()):

var body: some View 
    VStack 
        // your UI
    
    .onOpenUrl url in
        // do something with the deep link url
    

【讨论】:

以上是关于带有“App”协议深度链接的 SwiftUI macOS 应用程序打开了新的应用程序实例的主要内容,如果未能解决你的问题,请参考以下文章

深度编程 SwiftUI NavigationView 导航

如何简单快速地实现深度链接?

将 Firebase 身份验证与新的 @App 协议一起使用

如何在 SwiftUI 中从通知深层链接到屏幕?

带有常规文本的 SwiftUI 低不透明度按钮

带有 Mandrill 子域的通用深度链接