在 Mac 上的 SwiftUI 中处理“打开方式”中的多个 URL

Ste*_*e M 3 macos swift swiftui

在 SwiftUI 中,我们获得了onOpenURL(perform:)函数。但是,在 macOS 中,我们可以在 Finder 中选择多个文件,然后单击“打开方式”。如果我使用带有以下代码的应用程序打开这些文件:

@main
struct testURLMacApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onOpenURL { url in
                    print("RECEIVED \(url)")
                }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

看来此功能对于多个文件无法正常工作。有时似乎会调用一次执行闭包,或者有时如果幸运的话最多可以连续调用 2-3 次。有时它似乎会做一些奇怪的事情,例如打开重复的应用程序窗口。

有没有人找到解决方法,或者在 SwiftUI 应用程序的单个窗口中处理打开多个文件的正确方法?

编辑:这实际上是为了使现有的 iOS 应用程序能够在 Apple Silicon Mac 上运行。所以AppKit不可用。

Asp*_*eri 7

如上所述(见下文),它注册外部事件的处理程序,但仅首先使用它来创建新场景(可能是由于限制,可能是错误,可能是故意的,谁知道......)

演示1

因此,如果我们让.onOpenURL注册的处理程序捕获一个 URL 并为其创建新场景,则其他场景将保持未处理状态并被接收AppDelegate(见下文)。如果我们.onOpenURL完全删除,所有从 Finder 打开的 URL 都会转移到 AppDelegate。

使用 Xcode 13.4 / macOS 12.4 进行测试

在应用程序中

@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
    WindowGroup {
        ContentView()
    }
    // needed because WindowGroup scene seems have default
    // handler for external events, so opens new scene even
    // if no onOpenURL or userActivity callbacks are present
    .handlesExternalEvents(matching: [])   // << here !!
}
Run Code Online (Sandbox Code Playgroud)

并委托

class AppDelegate: NSObject, NSApplicationDelegate {
    func application(_ application: NSApplication, open urls: [URL]) {
        print("Unhandled: \(urls)")    // << here !!
    }
}
Run Code Online (Sandbox Code Playgroud)

完整的测试模块在这里