让我们分解一下:NSApplication 和 NSDocumentController 在基于NSDocument 的应用程序中为您免费提供-application:openFile: 或-openDocumentWithContentsOfURL:display:completionHandler:,以防NSFilenamesPboardType 和NSURLPboardType 掉落。
注意:我认为在后台这是使用kCoreEventClass/kAEOpenDocuments 和kInternetEventClass/kAEGetURL 的 NSAppleEventManager 事件处理程序实现的。
不幸的是,他们不处理NSFilesPromisePboardType。
让我们刷新我们的粘贴板知识:粘贴板在所有应用程序中共享。有用于复制、查找和拖动等任务的默认粘贴板。
当拖动开始时,应用程序会写入共享的拖动粘贴板。所以我们现在需要的只是关于拖放到 Dock 图标上的通知。
这就是NSService 发挥作用的地方:
<key>NSServices</key>
<array>
<dict>
<key>NSMessage</key>
<string>openService</string>
<key>NSSendTypes</key>
<array>
<string>public.data</string>
</array>
<key>NSMenuItem</key>
<dict>
<key>default</key>
<string>Open</string>
</dict>
</dict>
</array>
并在代码中设置:
- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
[NSApp setServicesProvider:self];
}
- (void)openService:(NSPasteboard *)serviceBoard
userData:(NSString *)userData
error:(NSString **)error
{
}
需要注意的是NSService 粘贴板不是NSDragPboard 粘贴板。
但是它们都是共享的,所以我们可以访问我们想要的:
NSPasteboard *dragPboard = [NSPasteboard pasteboardWithName:NSDragPboard];
if ([[dragPboard types] containsObject:NSFilesPromisePboardType])
{
}
下一个问题是我们没有-[NSDraggingInfo namesOfPromisedFilesDroppedAtDestination:]。
#import <ApplicationServices/ApplicationServices.h>
好老的 Carbon 让我们得到了保障。
PasteboardRef pboardRef = NULL;
PasteboardCreate((__bridge CFStringRef)NSDragPboard, &pboardRef);
PasteboardSetPasteLocation(pboardRef, (__bridge CFURLRef)temporaryDirectory);
NSString *urlString = [dragPboard stringForType:(NSString *)kPasteboardTypeFileURLPromise];
CFRelease(pboardRef);
从这里开始像任何其他承诺文件一样处理。