我已经设置了一个 SwiftUI 应用程序,它似乎接受拖放到停靠图标上的图像,但我无法弄清楚在应用程序代码中处理拖放图像的位置。
如何处理将图像(或任何特定文件)拖放到 SwiftUI 应用程序的停靠图标上?
背景
对于使用 NSApplication 的旧式 Swift 代码,处理应用程序停靠图标上的文件拖放可以通过两个步骤完成:
- 在 Info.plist 的 CFBundleDocumentTypes 中注册您想要接受的类型。
- 实施应用程序:打开文件: https://developer.apple.com/documentation/appkit/nsapplicationdelegate#//apple_ref/doc/uid/TP40008592-CH1-SW29(可能还有 application:openFiles:) 在你的 NSApplicationDelegate 上。
这被简洁地记录在一个单独的问题 https://stackoverflow.com/questions/2489961/dropping-files-onto-dock-icon-in-cocoa.
在 Swift UI 中创建应用程序委托(不起作用)
不过,SwiftUI 应用程序默认不提供应用程序委托。要实现这些功能,您必须做一些额外的工作 https://www.hackingwithswift.com/quick-start/swiftui/how-to-add-an-appdelegate-to-a-swiftui-app:
-
创建一个类来实现NSObject
and NSApplicationDelegate
(or UIApplicationDelegate
):
// or NSApplicationDelegate
class AppDelegate: NSObject, UIApplicationDelegate {
// ...
}
-
In your @main
App
实现,设置委托:
... : App {
// or @NSApplicationDelegateAdaptor
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
您现在可以实现应用程序委托方法!例如,这将在您的应用程序启动时打印:
func applicationWillFinishLaunching(_ notification: Notification) {
print("App Delegate loaded!")
}
But实现 openFile 函数不起作用:
func application(_ sender: NSApplication, openFile filename: String) -> Bool {
print("test", filename)
return false
}
func application(_ sender: NSApplication, openFiles filenames: [String]) {
print("another test", filenames)
}
将文件拖到应用程序上时,这些都不会打印出来。
现场代表?
这似乎是将 AppDelegate 功能分离到 SceneDelegate 中的一些工作的结果:
对于那些可能对此感到头疼的人来说,由于 appdelegate 功能的分离,现在在 scenedelegate 中调用等效的功能。等效的函数是 scene(_ scene: openURLContexts:)。我还没有研究过是否可以“选择退出”这一点,但就我的目的而言,没有理由不采用新行为
— m_bedwell 上应用程序(打开:选项:)没有被调用 https://developer.apple.com/forums/thread/119493(强调已添加)
但是我们的代码没有明显的方法来访问 SceneDelegate(这甚至可能不适用于 macOS?)。有一个有希望提出类似的问题 https://stackoverflow.com/questions/56498099/difference-between-scenedelegate-and-appdelegate.
有没有更好的办法?