如何创建Apple邮件插件 [英] How to create Apple mail plugin
问题描述
我将为OS X Mail.app应用程序创建一个邮件插件,用于一些其他功能。
I'm going to create a mail plugin for the OS X Mail.app application for some additional features.
我不知道从哪里开始,因为没有用于插件的官方文档。
I have no idea where to start as there is no official documentation for plugins.
任何人都可以帮助我,如何开始项目。
有任何初始链接或教程,请建议?
Can anyone please help me, how can I start the project. Is there any initial link or tutorial, please suggest?
推荐答案
如上所述,编写Apple Mail插件并不简单,因为它只有一个私人插件API,这是完全没有记录,可以更改与任何新版本的Mail.app。最好的代码示例是 GPGMail ,它是开放源代码&仍然有效(已在处理Yosemite支持)。这是我成功地做了开始(将放在github一旦完成):
As noted, writing Apple Mail plugins is not straightforward, since it only has a private plugin API, which is entirely undocumented and can change with any new version of Mail.app. The best code example is GPGMail, which is open source & still active (already working on Yosemite support). Here is what I successfully did to get started (will put it up on github once finished):
- 您需要在XCode中创建OSXBundle项目
- 扩展名为
mailbundle
(在项目生成设置中的包装下) - 一个包需要存储在
/ Library / Mail / Bundles
(作为构建阶段添加一个复制文件操作作为绝对路径目标和* .mailbundle从您的构建/文件夹作为要复制的项目) - 用于开发,我已将
/Applications/Mail.app
设置为在我的运行方案中可执行,以便在XCode中运行将构建它,复制包和启动邮件请注意,此时您将收到来自Mail的错误,表示您的插件无法启动并已停用。 - 您需要提供
SupportedPluginCompatibilityUUIDs
在我的从GPGMail偷走,这些使用新的邮件/ OSX版本更改 - 使用类转储从Mail.app的私有API生成头文件
- 起始点是
MVMailBundle
,你必须继承,并且有一个registerBundle
方法在
- 我从一个小的 MVMailBundle.h 头部包含在需要的地方(如GPGMail所做)
- you need to create an OSX "Bundle" project in XCode
- wrapper extension is
mailbundle
(under Packaging in the project Build settings) - a bundle needs to be stored under
~/Library/Mail/Bundles
(as Build Phase add a Copy Files action with that as absolute path destination and the *.mailbundle from your build/ folder as item to copy) - for development, I have set up
/Applications/Mail.app
as executable in my run scheme, so that Run in XCode will build it, copy the bundle and start mail; note that at this point you'll get an error from Mail that your plugin cannot be started and was disabled - you need to provide a list of
SupportedPluginCompatibilityUUIDs
in the Info.plist, I stole it from GPGMail, these change with new Mail/OSX versions - use class-dump to generate the header files from Mail.app's private API
- starting point is
MVMailBundle
, which you have to inherit from and which has aregisterBundle
method to hook you in- I extracted that from the huge generated header file in a small MVMailBundle.h header to include where needed (as done by GPGMail)
- c $ c> initialize 方法
- 并在Info.plist中将其设置为Principle class,以便在邮件加载bundle时运行。 app
#import <Cocoa/Cocoa.h>
@interface MyMailBundle : NSObject
+ (void)initialize;
@end
-
initialize
实现:以前,您可以使用简单的方法和直接继承为完成在信箱中,因为64位运行时的Objective-C < a>您必须使用GPGMail执行的动态方式:
- 使用
NSClassFromString
动态获取MVMailBundle
li>
- 和
class_setSuperclass
从< objc / runtime.h>
类继承它 c $>
- 然后调用
registerBundle
,作为MVMailBundle
(需要包含MVMailBundle.h
)
- 使用
initialize
implementation: previously, you could use the simple way and directly inherit as done in Letterbox, however, since 64-bit runtimes of Objective-C you have to use the dynamic way as done by GPGMail:- using
NSClassFromString
to dynamically get theMVMailBundle
class - and
class_setSuperclass
from<objc/runtime.h>
to have your own class inherit from it - and then call
registerBundle
on it casted asMVMailBundle
(requires include ofMVMailBundle.h
)
- using
b $ b
#import <objc/runtime.h>
#import "MVMailBundle.h"
#import "MyMailBundle.h"
@implementation MyMailBundle
+ (void)initialize
{
NSLog(@"Loading MyMail plugin...");
// since 64-bit objective-c runtimes, you apparently can't load
// symbols directly (i.e. through class inheritance) and have to
// resort to NSClassFromString
Class mvMailBundleClass = NSClassFromString(@"MVMailBundle");
// If this class is not available that means Mail.app
// doesn't allow plugins anymore or has changed the API
if (!mvMailBundleClass)
return;
// dynamically change super class hierarchy
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"
class_setSuperclass([self class], mvMailBundleClass);
#pragma GCC diagnostic pop
// register our plugin bundle in mail
[[((MyMailBundle *)self) class] registerBundle];
NSLog(@"Done registering MyMail plugin.");
}
@end
- 添加一些
NSLog
日志调用来验证正确的事情发生,它们将在XCode的控制台中显示,当运行/调试Mail.app从XCode或系统日志的Console.app - 这应该成功运行插件在邮件中没有错误!
- 接下来的步骤涉及疯狂的事情,如 MethodSwizzling 和 ClassPosing 修改Mail的行为,其中GPGMail可以是实用示例。 (还没有我自己)
- add some
NSLog
logging calls to verify the right thing is happening, they'll be visible in XCode's console when running/debugging Mail.app from within XCode or alternatively in the system logs of Console.app - This should successfully run the plugin in Mail with no error!
- The next steps involve crazy things like MethodSwizzling and ClassPosing to modify Mail's behavior, where GPGMail can be a helpful example. (Haven't been there myself yet)
以下是帮助我的一些资源:
For reference, here are some of the resources that helped me:
- GPGMail
- Adam Nash:准备为Mac OS X编写一个Apple Mail.app插件 - 一些很好的链接,但显然他从来没有完成项目,所以没有代码
- James R. Eagan:Demystifying Mail.app Plugins on
- Aaron Harnly:邮件插件模板 - 对于XCode 2我认为,不幸的是模板(下载zip)在Xcode中不再作为模板工作,但代码仍然可以用来查看
- Aaron Harnly:信箱来源 - 来自同一个家伙,但也从2007年,非常过时;包含模板自述文件,但它不包含如果你不能使用模板,真的很有帮助。
- GPGMail
- Adam Nash: Getting Ready to Write an Apple Mail.app Plug-in for Mac OS X - some good links, but apparently he never finished the project, so no code
- James R. Eagan: Demystifying Mail.app Plugins on Leopard - using PyObjC to write a plugin in Python, explains the basic mechansims, very useful
- Aaron Harnly: Mail Plugin Template - for XCode 2 I think, unfortunately the template (download a zip) doesn't work as template in Xcode anymore, but the code is still useful to look at
- Aaron Harnly: Letterbox sources - from the same guy, but also from 2007, very outdated; contains a readme from the template, though it doesn't really help if you can't use the template.
这篇关于如何创建Apple邮件插件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!