将承诺的文件拖放到 Dock 中的应用程序图标上 [英] Dropping promised files on to application icon in Dock

查看:29
本文介绍了将承诺的文件拖放到 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 的应用程序中的 NSApplicationNSDocumentControllerNSFilenamesPboardTypeNSURLPboardType 的情况下免费为您提供 -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/kAEOpenDocumentskInternetEventClass/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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆