【问题标题】:Drag and drop mail into OS X app将邮件拖放到 OS X 应用程序中
【发布时间】:2013-01-18 11:23:47
【问题描述】:

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

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

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

【问题讨论】:

  • 嗨@Adriana 我也遇到了同样的问题,你能发布你的解决方案吗?
  • @Nili 不幸的是我没有找到解决方案。

标签: objective-c macos drag-and-drop


【解决方案1】:

来自Drag and Drop Programming TopicsDragging Destinations portion

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

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

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

【讨论】:

  • 这对于导入整个eml文件很有用。有没有办法分解电子邮件的内容,例如进入“主题”、“发件人”字段?
【解决方案2】:

我想我会发布我对这个问题的答案,因为我挣扎了一段时间。此代码处理一个承诺,并简单地将丢弃的邮件复制到您的用户文件夹中名为 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
    }
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-06
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    相关资源
    最近更新 更多