使用 Swift 将邮件从 Mail 拖到 Dock 上

Posted

技术标签:

【中文标题】使用 Swift 将邮件从 Mail 拖到 Dock 上【英文标题】:Drag messages from Mail onto Dock using Swift 【发布时间】:2015-10-18 03:11:55 【问题描述】:

我正在尝试让我的应用程序接受直接从 Mail 拖放到我的应用程序停靠图标上的邮件消息。

我已点击此链接Dropping Files onto Dock Icon in Cocoa 并尝试转换为 Swift 和最新版本的 Xcode,但没有任何乐趣。

这是我的 AppDelegate.Swift 文件:

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate

    func application(sender: NSApplication, openFile filename: String) -> Bool
    
        println(filename)
        return true
    

    func application(sender: NSApplication, openFiles filenames: [String])
    
        println(filenames)
    

我已经为我的项目设置了文档类型:

当我将邮件文档从 Mail 拖到 Dock 中时,Dock 会突出显示,好像它想接受它但没有触发 openFiles 方法。

顺便说一句,如果我将邮件文件从 Mail 中拖到 Finder 中,然后将其拖到停靠图标上,它就可以正常工作。

邮件投递似乎只在 El Capitan 有效。我可以看到邮件现在可以放入 TextWrangler;这在 Yosemite 下不起作用。

作为奖励,我将向任何可以帮助我解决此问题的人提供额外的 50 赏金。

【问题讨论】:

Dropping Files onto Dock Icon in Cocoa的可能重复 我一直按照这个问题进行研究,并将其提炼成 Swift,但仍然无法正常工作。 我在想,既然你是从一个应用程序拖到另一个应用程序,你需要使用拖放(见这里:developer.apple.com/library/mac/documentation/Cocoa/Conceptual/…——它在 Cocoa 中,但无论如何都要浏览它)。我对此不是 100% 的,而且我已经完成了 0 次测试,因此是评论而不是答案,但可能值得研究。 【参考方案1】:

您可以通过将您的应用注册为服务来提取邮件项目的 URL,方法是将以下内容添加到应用的 info.plist:

<key>NSServices</key>
<array>
    <dict>
        <key>NSMessage</key>
        <string>itemsDroppedOnDock</string>
        <key>NSSendTypes</key>
        <array>
            <string>public.data</string>
        </array>
        <key>NSMenuItem</key>
        <dict>
            <key>default</key>
            <string>Open Mail</string>
        </dict>
    </dict>
</array>

那么您的 Swift 应用程序委托将如下所示:

import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate 

    func applicationDidFinishLaunching(aNotification: NSNotification) 
        NSApp.servicesProvider = self
    

    @objc func itemsDroppedOnDock(pboard: NSPasteboard, userData: NSString, error: UnsafeMutablePointer<NSString>) 
        // help from https://***.com/questions/14765063/get-dropped-mail-message-from-apple-mail-in-cocoa
        print("dropped types: \(pboard.types)")
        if let types = pboard.types 
            for type in types 
                print(" - type: \(type) string: \(pboard.stringForType(type))")
            
        

    

当您将邮件消息放到应用程序的 Dock 上时,输出将类似于:

dropped types: Optional(["public.url", "CorePasteboardFlavorType 0x75726C20", "dyn.ah62d4rv4gu8yc6durvwwaznwmuuha2pxsvw0e55bsmwca7d3sbwu", "Apple URL pasteboard type"])
 - type: public.url string: Optional("message:%3C2004768713.4671@tracking.epriority.com%3E")
 - type: CorePasteboardFlavorType 0x75726C20 string: Optional("message:%3C2004768713.4671@tracking.epriority.com%3E")
 - type: dyn.ah62d4rv4gu8yc6durvwwaznwmuuha2pxsvw0e55bsmwca7d3sbwu string: Optional("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<array>\n\t<string>message:%3C2004768713.4671@tracking.epriority.com%3E</string>\n\t<string></string>\n</array>\n</plist>\n")
 - type: Apple URL pasteboard type string: Optional("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<array>\n\t<string>message:%3C2004768713.4671@tracking.epriority.com%3E</string>\n\t<string></string>\n</array>\n</plist>\n")

不幸的是,您可能需要弄清楚如何将邮件 URL "message:%3C2004768713.4671@tracking.epriority.com%3E" 转换为实际的底层邮件文件,但这只是一个开始。

或者,如果您愿意接受在应用程序窗口中而不是在 Dock 上的拖放,您应该能够只使用 NSDraggingInfo.namesOfPromisedFilesDroppedAtDestination,这就是我希望 Finder 能够在您复制邮件时复制邮件的方式将邮件放在 Finder 窗口上(请注意,Finder 不会响应放在其停靠图标中的邮件消息,仅当它们被放在窗口上时)。

编辑:

请参阅Dropping promised files on to application icon in Dock,了解如何获得承诺文件。

【讨论】:

感谢您的帮助。我现在可以将我的消息放入扩展坞,但就像您只得到消息:URL 并且看不到如何获取消息正文一样。再往前一点,但现在卡住了。 见Dropping promised files on to application icon in Dock。 我尝试使用 NSSendTypes 的 NSSendTypes 实现这个答案(在 ObjC 中),不幸的是我的粘贴板只有两种类型:public.url-name 和 CorePasteboardFlavorType 0x75726C6E。也许 El Capitan 的新行为?我很高兴收到以下消息:… URL,但即使这样也没有运气。

以上是关于使用 Swift 将邮件从 Mail 拖到 Dock 上的主要内容,如果未能解决你的问题,请参考以下文章

Swift_TransportException无法与主机mywebsite.com建立连接

有没有办法建邮件核心的库,而不是直接把项目拖到我的项目中

如何将邮件数据从服务提供商传递到 laravel 4 中的 config/mail.php

Swift 发送邮件框架 Hedwig

使用 javax.mail 删除服务器上的电子邮件

如何指定PHP应该使用外部邮件服务器发送mail()?