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

时间:2021-12-26 20:48:33

I am trying to associate a certain filename extension with my macOS application, which I have managed to do by following this guide and can drag my file in to my application.

我试图将某个文件扩展名与我的macOS应用程序相关联,我已按照本指南设法完成该操作,并可将我的文件拖到我的应用程序中。

When I drag my file in, I get this exception in the console:

当我将文件拖入时,我在控制台中收到此异常:

2017-11-06 09:56:23.944202+0000 Test App[64192:2356795] [General] readFromData:ofType:error: is a subclass responsibility but has not been overridden.
2017-11-06 09:56:23.958166+0000 Test App[64192:2356795] [General] (
0 CoreFoundation 0x00007fff45f560fb exceptionPreprocess + 171
1 libobjc.A.dylib 0x00007fff6c844c76 objc_exception_throw + 48
2 CoreFoundation 0x00007fff45fe7bfd +[NSException raise:format:] + 205
3 AppKit 0x00007fff43a0b860 -[NSDocument readFromData:ofType:error:] + 253
4 AppKit 0x00007fff43a0b544 -[NSDocument readFromURL:ofType:error:] + 620
5 AppKit 0x00007fff436eb9b9 -[NSDocument _initWithContentsOfURL:ofType:error:] + 172
6 AppKit 0x00007fff436eb89e -[NSDocument initWithContentsOfURL:ofType:error:] + 231
7 AppKit 0x00007fff437c12dd -[NSDocumentController makeDocumentWithContentsOfURL:ofType:error:] + 628
8 AppKit 0x00007fff43a42578 __97-[NSDocumentController makeDocumentWithContentsOfURL:alternateContents:ofType:completionHandler:]_block_invoke + 91
9 AppKit 0x00007fff43a42512 -[NSDocumentController makeDocumentWithContentsOfURL:alternateContents:ofType:completionHandler:] + 176
10 AppKit 0x00007fff437c0493 __80-[NSDocumentController openDocumentWithContentsOfURL:display:completionHandler:]_block_invoke + 880
11 AppKit 0x00007fff43a411b9 __144-[NSDocumentController _coordinateReadingAndGetAlternateContentsForOpeningDocumentAtURL:resolvingSymlinks:thenContinueOnMainThreadWithAccessor:]_block_invoke_4 + 31
12 AppKit 0x00007fff43a41542 __144-[NSDocumentController _coordinateReadingAndGetAlternateContentsForOpeningDocumentAtURL:resolvingSymlinks:thenContinueOnMainThreadWithAccessor:]_block_invoke_2.970 + 149
13 AppKit 0x00007fff43a4147d __144-[NSDocumentController _coordinateReadingAndGetAlternateContentsForOpeningDocumentAtURL:resolvingSymlinks:thenContinueOnMainThreadWithAccessor:]_block_invoke.969 + 138
14 AppKit 0x00007fff43a4133f __144-[NSDocumentController _coordinateReadingAndGetAlternateContentsForOpeningDocumentAtURL:resolvingSymlinks:thenContinueOnMainThreadWithAccessor:]_block_invoke.964 + 254
15 CoreFoundation 0x00007fff45eee52c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK
+ 12
16 CoreFoundation 0x00007fff45ed0f43 __CFRunLoopDoBlocks + 275
17 CoreFoundation 0x00007fff45ed0d08 __CFRunLoopRun + 3128
18 CoreFoundation 0x00007fff45ecfe43 CFRunLoopRunSpecific + 483
19 HIToolbox 0x00007fff451ef866 RunCurrentEventLoopInMode + 286
20 HIToolbox 0x00007fff451ef5d6 ReceiveNextEventCommon + 613
21 HIToolbox 0x00007fff451ef354 _BlockUntilNextEventMatchingListInModeWithFilter + 64
22 AppKit 0x00007fff434ec9f7 _DPSNextEvent + 2085
23 AppKit 0x00007fff43c81d98 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 3044
24 AppKit 0x00007fff434e1805 -[NSApplication run] + 764
25 AppKit 0x00007fff434b09a6 NSApplicationMain + 804
26 Test App 0x000000010004cd1d main + 13
27 libdyld.dylib 0x00007fff6d433145 start + 1
28 ??? 0x0000000000000003 0x0 + 3

2017-11-06 09:56:23.944202 + 0000 Test App [64192:2356795] [General] readFromData:ofType:error:是一个子类责任但尚未被覆盖。 2017-11-06 09:56:23.958166 + 0000 Test App [64192:2356795] [General](0 CoreFoundation 0x00007fff45f560fb exceptionPreprocess + 171 1 libobjc.A.dylib 0x00007fff6c844c76 objc_exception_throw + 48 2 CoreFoundation 0x00007fff45fe7bfd + [NSException raise:format:] + 205 3 AppKit 0x00007fff43a0b860 - [NSDocument readFromData:ofType:error:] + 253 4 AppKit 0x00007fff43a0b544 - [NSDocument readFromURL:ofType:error:] + 620 5 AppKit 0x00007fff436eb9b9 - [NSDocument _initWithContentsOfURL:ofType:error:] + 172 6 AppKit 0x00007fff436eb89e - [NSDocument initWithContentsOfURL:ofType:error:] + 231 7 AppKit 0x00007fff437c12dd - [NSDocumentController makeDocumentWithContentsOfURL:ofType:error:] + 628 8 AppKit 0x00007fff43a42578 __97- [NSDocumentController makeDocumentWithContentsOfURL:alternateContents:ofType:completionHandler:] _ block_invoke + 91 9 AppKit 0x00007fff43a42512 - [NSDocumentController makeDocumentWithContentsOfURL:alternateContents:ofType:completionHandler:] + 176 10 AppKit 0x00007fff437c0493 __80- [N SDocumentController openDocumentWithContentsOfURL:显示:completionHandler:] _ block_invoke + 880 11了AppKit 0x00007fff43a411b9 __144- [NSDocumentController _coordinateReadingAndGetAlternateContentsForOpeningDocumentAtURL:resolvingSymlinks:thenContinueOnMainThreadWithAccessor:] _ block_invoke_4 + 31 12了AppKit 0x00007fff43a41542 __144- [NSDocumentController _coordinateReadingAndGetAlternateContentsForOpeningDocumentAtURL:resolvingSymlinks:thenContinueOnMainThreadWithAccessor:] _ block_invoke_2.970 + 149 13了AppKit 0x00007fff43a4147d __144- [NSDocumentController _coordinateReadingAndGetAlternateContentsForOpeningDocumentAtURL:resolvingSymlinks:thenContinueOnMainThreadWithAccessor:] _ block_invoke.969 + 138 14了AppKit 0x00007fff43a4133f __144- [NSDocumentController _coordinateReadingAndGetAlternateContentsForOpeningDocumentAtURL:resolvingSymlinks:thenContinueOnMainThreadWithAccessor:] _ block_invoke.964 + 254 15的CoreFoundation 0x00007fff45eee52c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK + 12 16 CoreFoundatio Ñ0x00007fff45ed0f43 __CFRunLoopDoBlocks + 275 17的CoreFoundation 0x00007fff45ed0d08 __CFRunLoopRun + 3128 18的CoreFoundation 0x00007fff45ecfe43 CFRunLoopRunSpecific + 483 19使HIToolbox 0x00007fff451ef866 RunCurrentEventLoopInMode + 286 20使HIToolbox 0x00007fff451ef5d6 ReceiveNextEventCommon + 613 21使HIToolbox 0x00007fff451ef354 _BlockUntilNextEventMatchingListInModeWithFilter + 64 22了AppKit 0x00007fff434ec9f7 _DPSNextEvent + 2085 23了AppKit 0x00007fff43c81d98 - [的NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 3044 24 AppKit 0x00007fff434e1805 - [NSApplication run] + 764 25 AppKit 0x00007fff434b09a6 NSApplicationMain + 804 26 Test App 0x000000010004cd1d main + 13 27 libdyld.dylib 0x00007fff6d433145 start + 1 28 ??? 0x0000000000000003 0x0 + 3

I've tried implementing the NSApplicationDelegate openFile functions but none of them are called when I drag the file on to the app:

我已经尝试实现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
    }
}

How do I get access to the filename and contents of the "dragged in" file? I am using XCode 9.0.1 and Swift 4.

如何访问“拖入”文件的文件名和内容?我正在使用XCode 9.0.1和Swift 4。

Edit:

Here is my Info.plist

这是我的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>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>

So I would have expected application(_ sender: NSApplication, openFile filename: String) to be called when I drag the file on to the app when it's in the Dock...

因此,当我在Dock中将文件拖到应用程序时,我会预期应用程序(_ sender:NSApplication,openFile filename:String)被调用...

1 个解决方案

#1


0  

There are a number of points here to address:

这里有很多要点:

  • if you're working in macOS 10.12 or below, you should implement either openFile or openFiles. openURLs is 10.13+ - but you definitely don't need both
  • 如果你在macOS 10.12或更低版本中工作,你应该实现openFile或openFiles。 openURLs是10.13+ - 但你绝对不需要两者

  • openFile will be called for each of multiple files; if openFiles is present, openFile will not be called, even if you open only a single file
  • 将为多个文件中的每一个调用openFile;如果存在openFiles,即使您只打开一个文件,也不会调用openFile

  • I have no idea what openTempFile (or openUntitledFile) are about; I haven't been able to get anyone to call either

    我不知道openTempFile(或openUntitledFile)是关于什么的;我也无法让任何人打电话

  • openFile(s) get called when you have successfully registered a UTI with the system; double-clicking an appropriate file(s) in the Finder, choosing 'open' or dragging the file onto the dock icon of your app all send an open message that gets handled by the AppDelegate. I am not clear what you mean by 'When I drag my file in': if you drag your file onto the app icon in the Finder, openFile(s) should be called; your wording makes me think that your drag destination is part of your application's interface, in which case you need to handle dragging yourself.

    当您在系统中成功注册UTI时,会调用openFile;双击Finder中的相应文件,选择“打开”或将文件拖到应用程序的停靠栏图标上,都会发送一条由AppDelegate处理的打开消息。我不清楚'当我将文件拖入'时你的意思是:如果你将文件拖到Finder中的app图标上,应该调用openFile;你的措辞让我觉得你的拖动目的地是应用程序界面的一部分,在这种情况下你需要自己处理拖动。

Also check - because the linked (iOS) guide does not address this - that you have set your NSDocument class: your example says 'NSDocument', but there is an extreme likelihood that your application uses a custom subclass; so you need to set the 'Class' to that name.

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

#1


0  

There are a number of points here to address:

这里有很多要点:

  • if you're working in macOS 10.12 or below, you should implement either openFile or openFiles. openURLs is 10.13+ - but you definitely don't need both
  • 如果你在macOS 10.12或更低版本中工作,你应该实现openFile或openFiles。 openURLs是10.13+ - 但你绝对不需要两者

  • openFile will be called for each of multiple files; if openFiles is present, openFile will not be called, even if you open only a single file
  • 将为多个文件中的每一个调用openFile;如果存在openFiles,即使您只打开一个文件,也不会调用openFile

  • I have no idea what openTempFile (or openUntitledFile) are about; I haven't been able to get anyone to call either

    我不知道openTempFile(或openUntitledFile)是关于什么的;我也无法让任何人打电话

  • openFile(s) get called when you have successfully registered a UTI with the system; double-clicking an appropriate file(s) in the Finder, choosing 'open' or dragging the file onto the dock icon of your app all send an open message that gets handled by the AppDelegate. I am not clear what you mean by 'When I drag my file in': if you drag your file onto the app icon in the Finder, openFile(s) should be called; your wording makes me think that your drag destination is part of your application's interface, in which case you need to handle dragging yourself.

    当您在系统中成功注册UTI时,会调用openFile;双击Finder中的相应文件,选择“打开”或将文件拖到应用程序的停靠栏图标上,都会发送一条由AppDelegate处理的打开消息。我不清楚'当我将文件拖入'时你的意思是:如果你将文件拖到Finder中的app图标上,应该调用openFile;你的措辞让我觉得你的拖动目的地是应用程序界面的一部分,在这种情况下你需要自己处理拖动。

Also check - because the linked (iOS) guide does not address this - that you have set your NSDocument class: your example says 'NSDocument', but there is an extreme likelihood that your application uses a custom subclass; so you need to set the 'Class' to that name.

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