将承诺的文件拖放到 Dock 中的应用程序图标上
Dropping promised files on to application icon in Dock
当拖放到 Dock 中的应用程序图标时,是否可以在沙盒应用程序中打开承诺的文件 NSFilesPromisePboardType
? Dock 图标正在接受放置,但从未调用 -application:openFile:
。
我找到的唯一参考是沙盒前:
Accepting iCal events dropped on my application's icon
rdar://47917787
让我们分解一下:基于 NSDocument
的应用程序中的 NSApplication
和 NSDocumentController
在 [=20 的情况下免费提供 -application:openFile:
或 -openDocumentWithContentsOfURL:display:completionHandler:
=] 和 NSURLPboardType
下降。
注意:我认为 在幕后,这是使用 kCoreEventClass
/kAEOpenDocuments
和 kInternetEventClass
/[ 的 NSAppleEventManager 事件处理程序实现的=25=].
很遗憾,他们不处理 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);
从这里开始像处理任何其他承诺文件一样处理。
当拖放到 Dock 中的应用程序图标时,是否可以在沙盒应用程序中打开承诺的文件 NSFilesPromisePboardType
? Dock 图标正在接受放置,但从未调用 -application:openFile:
。
我找到的唯一参考是沙盒前: Accepting iCal events dropped on my application's icon
rdar://47917787
让我们分解一下:基于 NSDocument
的应用程序中的 NSApplication
和 NSDocumentController
在 [=20 的情况下免费提供 -application:openFile:
或 -openDocumentWithContentsOfURL:display:completionHandler:
=] 和 NSURLPboardType
下降。
注意:我认为 在幕后,这是使用 kCoreEventClass
/kAEOpenDocuments
和 kInternetEventClass
/[ 的 NSAppleEventManager 事件处理程序实现的=25=].
很遗憾,他们不处理 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);
从这里开始像处理任何其他承诺文件一样处理。