2

我希望能够从 Outlook for Mac 和 Mail.app 拖放和发送电子邮件到 OS X 应用程序。如果我从我的查找器拖放和发送电子邮件(拖动文件),则调用以下内容:

- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender

但是,如果我从 Outlook for Mac 或 Mail.app 拖放,则不会调用该方法。我对如何实现这一目标有点迷茫。有任何想法吗?

4

2 回答 2

8

拖放编程主题拖动目的地部分

要接收拖动操作,您必须通过向对象发送 registerForDraggedTypes: 消息来注册窗口或视图将接受的粘贴板类型,该消息在 NSWindow 和 NSView 中都定义,并实现 NSDraggingDestination 协议中的几个方法。在拖动会话期间,候选目的地仅在目的地注册为与被拖动的粘贴板数据类型匹配的粘贴板类型时才会收到 NSDraggingDestination 消息。当图像进入、在内部移动、然后退出或在目的地边界内释放时,目的地会收到这些消息。

为了接受来自 Mail 的拖拽,您需要知道要注册的粘贴板类型。您可以使用 ClipboardViewer 来发现 Mail 在拖动粘贴板上放置了哪些类型的数据(在Xcode 最新版本的辅助工具包中提供)。启动 ClipboardViewer 并从工具栏中的组合框中选择拖动剪贴板。切换回 Mail 并简单地拖动一条消息,然后返回 ClipboardViewer。您应该会在边栏中看到许多粘贴板类型。特别感兴趣的是public.urlcom.apple.pasteboard.promised-file-content-type类型。前者表示一个 URL 在粘贴板上。后者是一个文件承诺在粘贴板上。URL 往往是一个很好的起点,但在这种特殊情况下,我们可以看到 URL 不像文件 URL 那样有用,它是一个相当不透明的消息 URL。registerForDraggedTypes:这意味着我们需要处理文件承诺,因此在配置我们的视图以接收拖动时,我们应该调用NSFilesPromisePboardType.

Dragging File Promises文档的第二部分具体概述了如何处理接收 Promise。总而言之,您-namesOfPromisedFilesDroppedAtDestination:从内部调用拖动的发送者,performDragOperation:让他们将拖动的数据写入您选择的位置(例如,履行承诺)。concludeDragOperation:拖动的发起者将在 AppKit 调用您的对象之前将数据写入磁盘。在任何时候,concludeDragOperation:您都可以从磁盘加载删除的文件并根据需要处理它们。

于 2013-01-19T06:02:00.603 回答
0

我想我会发布我对这个问题的答案,因为我挣扎了一段时间。这段代码处理一个承诺,并简单地将丢弃的邮件复制到您的用户文件夹中名为 Drop Stuff 的文件夹中。它也适用于任何文件,并且似乎适用于其他应用程序,包括地址簿和提醒等。它不适用于复制多个文件(或邮件消息)。

import Cocoa

class DropArea: NSImageView, NSDraggingDestination 
{

    override func drawRect(dirtyRect: NSRect) 
    {
        super.drawRect(dirtyRect)
    }

    required init?(coder: NSCoder)
    {
        let types = [NSFilenamesPboardType, NSURLPboardType, NSPasteboardTypeTIFF, NSFilesPromisePboardType]
        super.init(coder: coder)
        registerForDraggedTypes(types)
    }

    override func draggingEntered(sender: NSDraggingInfo) -> NSDragOperation
    {
        return .Copy
    }

    override func performDragOperation(sender: NSDraggingInfo) -> Bool
    {
        var error: NSError?

        var folderPath = NSHomeDirectory()+"/Drop Stuff/"
        if (!NSFileManager.defaultManager().fileExistsAtPath(folderPath))
        {
            NSFileManager.defaultManager().createDirectoryAtPath(folderPath, withIntermediateDirectories: true, attributes: nil, error: &error)
        }

        var folderURL = NSURL(fileURLWithPath: folderPath)
        var f = sender.namesOfPromisedFilesDroppedAtDestination(folderURL!)
        println("Copied to \(folderPath)")
        return true
    }
}

当然欢迎任何改进此代码的建议:-)

于 2015-05-19T09:19:46.850 回答