我已经设置了一个SwiftUI应用程序,它似乎可以接受放在dock图标上的图像,但我不知道在应用程序代码中在哪里处理掉的图像。
如何将图像(或任何特定文件(拖放到SwiftUI应用程序的停靠图标上?
背景
对于使用NSApplication的老式Swift代码,可以通过两个步骤来处理应用程序停靠图标上的文件丢弃:
- 在Info.plist中的CFBundleDocumentTypes中注册要接受的类型
- 在NSApplicationDelegate上实现应用程序:openFile:(可能还有应用程序:openFiles:(
这在另一个问题中有简明扼要的记录。
在Swift UI中创建应用程序委托(不起作用(
不过,SwiftUI应用程序默认情况下不提供应用程序委派。要实现这些功能,您必须做一些额外的工作:
-
创建一个实现
NSObject
和NSApplicationDelegate
(或UIApplicationDelegate
(的类:// or NSApplicationDelegate class AppDelegate: NSObject, UIApplicationDelegate { // ... }
-
在
@main
App
实现中,设置代理:... : App { // or @NSApplicationDelegateAdaptor @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
您现在可以实现应用程序委派方法了!例如,这将在您的应用程序启动时打印:
func applicationWillFinishLaunching(_ notification: Notification) {
print("App Delegate loaded!")
}
但是实现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功能分离到SceneDelegates:的一些工作的结果
对于那些可能会为此感到头疼的人,由于appdelegate的功能分离,现在在场景中调用了等效的功能等价的ish函数是scene(_scene:openURLContext:(。我还没有研究是否有可能"选择退出",但就我的目的而言,没有理由不采用新的行为
应用程序上的m_bedwell(打开:选项:(未被调用(添加了强调(
但是,我们的代码没有明显的方法访问SceneDelegate(这甚至可能不适用于macOS?(。还有一个很有希望的类似问题。
有更好的方法吗?
在SwiftUI中,有一种非常简单的方法可以处理掉到Dock图标上的内容!
-
更新你的Info.plist以表明你的应用程序支持你想要的文件类型(就像在旧的应用程序中一样(:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <!-- ... --> <key>CFBundleTypeName</key> <string>Image files</string> <key>CFBundleTypeRole</key> <string>Viewer</string> <key>LSHandlerRank</key> <string>Default</string> <key>LSItemContentTypes</key> <array> <string>public.image</string> </array> </dict> </plist>
-
在
body
和App
中,使用onOpenURL:var body: some Scene { WindowGroup { ContentView() .onOpenURL { (url) in // Handle url here } } }
--ianivs(如何使用新的SwiftUI@main启动处理URL回调?(