将承诺的文件拖放到 Dock 中的应用程序图标上
Posted
技术标签:
【中文标题】将承诺的文件拖放到 Dock 中的应用程序图标上【英文标题】:Dropping promised files on to application icon in Dock 【发布时间】:2016-02-20 23:24:36 【问题描述】:当拖放到 Dock 中的应用程序图标时,是否可以在沙盒应用程序中打开承诺的文件 NSFilesPromisePboardType
? Dock 图标正在接受拖放,但从未调用过 -application:openFile:
。
我找到的唯一参考是预沙箱: Accepting iCal events dropped on my application's icon
rdar://47917787
【问题讨论】:
【参考方案1】:让我们分解一下: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);
从这里开始像任何其他承诺文件一样处理。
【讨论】:
我想将一封电子邮件从 Mail 拖到我的应用程序的 Dock 图标。我使用了上面的代码(将 NSService 键添加到我的 Info.plist 文件中,设置服务提供者并添加方法 openService)。但是方法 openService 没有被调用。我能做什么?以上是关于将承诺的文件拖放到 Dock 中的应用程序图标上的主要内容,如果未能解决你的问题,请参考以下文章