使用swift在macOS中实现文档拖动到应用程序



我正在尝试将某个文件扩展名与我的macOS应用程序关联起来,我已经按照本指南完成了这一操作,并且可以将我的文件拖到我的应用程序中。

当我拖动我的文件时,我在控制台中得到这个异常:

2017-11-06 09:56:23.944202+000测试应用程序[64192:2356795][General]readFromData:Type:error:是子类责任,但尚未覆盖
2017-11-06 09:56:23.958166+000测试应用程序[64192:2356795][概述](
0 CoreFoundation 0x00007fff45f560fb异常预处理+171
1 libobjc.A.dylib 0x00007fff6c844c76 objc_exception_show+48
2 CoreFoundation 0x0007fff45fe7bfd+[NException提升:格式:]+205
3 AppKit 0x00007fff43a0b860-[NSDocument readFromData:类型:错误:]+253
4 AppKit 0x0007fff43A0b544-[NSDDocument readFromURL:类型:误差:]+620
5 AppKit 0x00007 fff436eb9b9-[NSDdocument_initWithContentsOfURL:类型:误差:]+172
6 AppKit0x00007fff436eb89e-[NSDocument initWithContentsOfURL:类型:错误:]+231
7 AppKit 0x00007fff437c12dd-[NSDDocumentController makeDocumentWithContentsOfURL:类型:误差:]+628
8 AppKit 0x00007 fff43a42578 __97-[NSDdocumentController makeDocumentWithContentsOfURL:alternateContents:类型:完成处理程序:]_block_invoke+91
9AppKit 0x00007fff43a42512-[NSDocumentController使DocumentWithContentsOfURL:alternateContents:类型:完成处理程序:]+176
10 AppKit 0x00007 fff437c0493 __80-[NSDDocumentController打开DocumentWithContents OfURL:显示:完成处理器:]_block_invoke+880
11 AppKit-[NSDocumentController_coordinateReadingAndGetAlternateContentsForOpeningDocumentAtURL:解析Symlinks:thenContinueOnThreadWithAccessor:]_block_invoke_4+31
12 AppKit 0x00007fff43a41542 __144-[NSDocument Controller_cordinateReadingandGetAlternate ContentsForopeningDocumentAtURL:解析Symlinks:thenContinueNMainThreadWithAccessor:]_block_invoke_2.970+149
13 AppKit 0x00007fff43a147d __144-[NSDocumentController _coordinateReadingAndGetAlternateContentsForOpeningDocumentAtURL:resolvingSymlinks:thenContinueOnThreadWithAccessor:]_block_invoke.969+138-[NSDocumentController_coordinateReadingAndGetAlternateContentsForOpeningDocumentAtURL:resolvingSymlinks:thenContinueOnThreadWithAccessor:]_block_invoke.964+254
15 CoreFoundation 0x00007fff45eee52c__CFRUNLOOP_IS_CALLING_OUT_TO_A_block
+12
16 CoreFoundation 0x0007fff45ed0f43__CFRunLoopDoBlocks+275
17 CoreFoundation0x00007fff45ed0d08 __CFRunLoopRun+3128
18 CoreFoundation 0x00007fff45ecfe43 CFRunLoop RunSpecific+483
19 HIToolbox 0x00007fff351ef866 RunCurrentEventLoopInMode+286
20 HIToolbox 0x0007fff451ef5d6 ReceiveNextEventCommon+613
21 HIToolbox_BlockUntilNextEventMatchingListInModeWithFilter+64
22 AppKit 0x00007fff434ec9f7 _DPSNextEvent+2085
23 AppKit 0x00007 fff43c81d98-[NApplication(NSEvent)_nextEventMatchingEventMask:untilDate:inMode:出列:]+3044
24 AppKit 0x000.07fff434e1805-[NApplication run]+764
25 AppKit0x00007fff434b09a6 NSApplicationMain+804
26测试应用程序0x000000010004cd1d main+13
27 libdyld.dylib 0x00007fff6d433145启动+1
28???0x0000000000000003 0x0+3

我尝试过实现NSApplicationDelegate openFile函数,但当我将文件拖到应用程序上时,它们都没有被调用:

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
func application(_ application: NSApplication, open urls: [URL]) {
}
func application(_ sender: NSApplication, openFile filename: String) -> Bool {
return false
}
func application(_ sender: NSApplication, openFiles filenames: [String]) {
}
func application(_ sender: NSApplication, openTempFile filename: String) -> Bool {
return false
}
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Insert code here to initialize your application
}
func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}
}

如何访问"拖入"文件的文件名和内容?我使用的是XCode 9.0.1和Swift 4。

编辑:

这是我的信息列表

<?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>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>tal</string>
</array>
<key>CFBundleTypeIconFile</key>
<string></string>
<key>CFBundleTypeMIMETypes</key>
<array>
<string></string>
</array>
<key>CFBundleTypeName</key>
<string>Layout File</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>com.testapp.layout</string>
</array>
<key>LSTypeIsPackage</key>
<integer>0</integer>
<key>NSDocumentClass</key>
<string>NSDocument</string>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>v1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string></string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.video</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2017. All rights reserved.</string>
<key>NSMainStoryboardFile</key>
<string>Main</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>Layout File</string>
<key>UTTypeIconFile</key>
<string></string>
<key>UTTypeIdentifier</key>
<string>com.testapp.layout</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>tal</string>
</array>
</dict>
</dict>
<dict/>
</array>
</dict>
</plist>

因此,当我将文件拖到Dock中的应用程序上时,我本以为会调用application(_ sender: NSApplication, openFile filename: String)。。。

这里有许多点需要解决:

  • 如果你在macOS 10.12或更低版本中工作,你应该实现openFile或openFiles。openURL是10.13+,但你绝对不需要两者
  • 将为多个文件中的每个文件调用openFile;如果存在openFiles,即使只打开一个文件,也不会调用openFile
  • 我不知道openTempFile(或openUnttledFile)是关于什么的;我还没能让任何人给打电话

  • 在系统中成功注册UTI后,会调用openFile;在Finder中双击适当的文件,选择"打开"或将文件拖到应用程序的dock图标上,都会发送一条由AppDelegate处理的打开消息。我不清楚你说的"当我把文件拖进去时"是什么意思:如果你把文件拖到Finder中的应用程序图标上,应该调用openFile;您的措辞让我认为您的拖动目的地是应用程序界面的一部分,在这种情况下,您需要自己处理拖动。

还要检查-因为链接的(iOS)指南没有解决这个问题-你已经设置了你的NSDocument类:你的例子说"NSDocument",但你的应用程序使用自定义子类的可能性很高;所以您需要将"Class"设置为该名称。

最新更新