【问题标题】:Dropping promised files on to application icon in Dock将承诺的文件拖放到 Dock 中的应用程序图标上
【发布时间】:2016-02-20 23:24:36
【问题描述】:

当拖放到 Dock 中的应用程序图标时,是否可以在沙盒应用程序中打开承诺的文件 NSFilesPromisePboardType? Dock 图标正在接受拖放,但从未调用过 -application:openFile:

我找到的唯一参考是预沙箱: Accepting iCal events dropped on my application's icon

rdar://47917787

【问题讨论】:

    标签: macos cocoa drag-and-drop sandbox mac-app-store


    【解决方案1】:

    让我们分解一下:NSApplicationNSDocumentController 在基于NSDocument 的应用程序中为您免费提供-application:openFile:-openDocumentWithContentsOfURL:display:completionHandler:,以防NSFilenamesPboardTypeNSURLPboardType 掉落。

    注意:我认为在后台这是使用kCoreEventClass/kAEOpenDocumentskInternetEventClass/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 没有被调用。我能做什么?
    猜你喜欢
    • 2011-03-10
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多