将承诺的文件拖放到 Dock 中的应用程序图标上 [英] Dropping promised files on to application icon in Dock
问题描述
当拖放到 Dock 中的应用程序图标时,是否可以在沙盒应用程序中打开承诺的文件 NSFilesPromisePboardType
?Dock 图标正在接受放置,但永远不会调用 -application:openFile:
.
Is it possible to open promised files NSFilesPromisePboardType
in sandboxed application when dropping on to application icon in Dock? The Dock icon is accepting the drop, but -application:openFile:
is never called.
我找到的唯一参考是 pre sandbox:接受 iCal 事件丢弃在我的应用程序图标上
The only reference I found are pre sandbox: Accepting iCal events dropped on my application's icon
rdar://47917787
rdar://47917787
推荐答案
让我们分解一下:基于 NSDocument
的应用程序中的 NSApplication
和 NSDocumentController
在 NSFilenamesPboardType
和 NSURLPboardType
的情况下免费为您提供 -application:openFile:
或 -openDocumentWithContentsOfURL:display:completionHandler:
> 滴.
Let's break this down: NSApplication
and NSDocumentController
in NSDocument
based apps gives you -application:openFile:
or -openDocumentWithContentsOfURL:display:completionHandler:
for free in case of NSFilenamesPboardType
and NSURLPboardType
drops.
注意:我认为在后台,这是使用 kCoreEventClass
/kAEOpenDocuments
和 kInternetEventClass的 NSAppleEventManager 事件处理程序实现的代码>/
kAEGetURL
.
Note: I think under the hood this is implement with the NSAppleEventManager event handlers for kCoreEventClass
/kAEOpenDocuments
and kInternetEventClass
/kAEGetURL
.
不幸的是,他们不处理 NSFilesPromisePboardType
.
Unfortunately they don't handle NSFilesPromisePboardType
.
让我们刷新我们的粘贴板知识:粘贴板在所有应用程序中共享.有用于复制、查找和拖动等任务的默认粘贴板.
Lets refresh our pasteboard knowledge: The pasteboard is shared amongst all application. There are default pasteboards for tasks like copy, find, and drag.
当拖动开始时,应用程序会写入共享的拖动粘贴板.所以我们现在需要的只是关于拖放到 Dock 图标上的通知.
When the drag starts the application writes into the shared drag pasteboard. So all we need now is notification about the drop onto Dock icon.
这就是 NSService
发挥作用的地方:
This is where NSService
comes into play:
<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
粘贴板.
One caveat is that the NSService
pasteboard is not the NSDragPboard
pasteboard.
但是它们都是共享的,所以我们可以访问我们想要的:
But they are all shared, so we can just access the one we want:
NSPasteboard *dragPboard = [NSPasteboard pasteboardWithName:NSDragPboard];
if ([[dragPboard types] containsObject:NSFilesPromisePboardType])
{
}
下一个问题是我们没有-[NSDraggingInfo namesOfPromisedFilesDroppedAtDestination:]
.
The next problem is that we don't have -[NSDraggingInfo namesOfPromisedFilesDroppedAtDestination:]
.
#import <ApplicationServices/ApplicationServices.h>
好老的 Carbon 让我们得到了保障.
Good old Carbon got us covered.
PasteboardRef pboardRef = NULL;
PasteboardCreate((__bridge CFStringRef)NSDragPboard, &pboardRef);
PasteboardSetPasteLocation(pboardRef, (__bridge CFURLRef)temporaryDirectory);
NSString *urlString = [dragPboard stringForType:(NSString *)kPasteboardTypeFileURLPromise];
CFRelease(pboardRef);
从这里开始像任何其他承诺文件一样处理.
Handle like any other promise file from here on.
这篇关于将承诺的文件拖放到 Dock 中的应用程序图标上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!