将承诺的文件拖放到Dock中的应用程序图标上 [英] Dropping promised files on to application icon in Dock
问题描述
当在Dock中的应用程序图标上时,是否可以在沙盒应用程序中打开承诺的文件 NSFilesPromisePboardType
? Dock图标接受下降,但 -application:openFile:
从未调用。
找到的是预置沙箱:
接受iCal事件已删除我的应用程式图示
让我们分解下来:<$ c $基于NSDocument 的应用程序中的NSApplication 和 NSDocumentController
-application:openFile:或 -openDocumentWithContentsOfURL:display:completionHandler:
免费使用 NSFilenamesPboardType
和 NSURLPboardType
丢弃。
注意:我 下面是使用NSAppleEventManager事件处理程序实现 kCoreEventClass
/ kAEOpenDocuments
和 kInternetEventClass
/ kAEGetURL
p>
不幸的是,他们不处理 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>默认< / key>
< string>打开< / string>
< / dict>
< / dict>
< / array>
并在代码中设置:
- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
[NSApp setServicesProvider:self];
}
- (void)openService:(NSPasteboard *)serviceBoard
userData:(NSString *)userData
错误:(NSString **)错误$ b $需要注意的是, NSService code>粘贴板不是 NSDragPboard
粘贴板。
但他们都是共享的,所以我们可以访问我们想要的:
NSPasteboard * dragPboard = [NSPasteboard pasteboardWithName:NSDragPboard];
if([[dragPboard types] containsObject:NSFilesPromisePboardType])
{
}
下一个问题是我们没有 - [NSDraggingInfo namesOfPromisedFilesDroppedAtDestination:]
。
#import< ApplicationServices / ApplicationServices.h>
好的旧碳让我们得到保护。
PasteboardRef pboardRef = NULL;
PasteboardCreate((__ bridge CFStringRef)NSDragPboard,& pboardRef);
PasteboardSetPasteLocation(pboardRef,(__bridge CFURLRef)temporaryDirectory);
NSString * urlString = [dragPboard stringForType:(NSString *)kPasteboardTypeFileURLPromise];
CFRelease(pboardRef);
从这里处理任何其他promise文件。
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.
The only reference I found are pre sandbox:
Accepting iCal events dropped on my application's icon
解决方案 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.
Note: I think under the hood this is implement with the NSAppleEventManager event handlers for kCoreEventClass
/kAEOpenDocuments
and kInternetEventClass
/kAEGetURL
.
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.
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.
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>
And set it up in code:
- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
[NSApp setServicesProvider:self];
}
- (void)openService:(NSPasteboard *)serviceBoard
userData:(NSString *)userData
error:(NSString **)error
{
}
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])
{
}
The next problem is that we don't have -[NSDraggingInfo namesOfPromisedFilesDroppedAtDestination:]
.
#import <ApplicationServices/ApplicationServices.h>
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屋!