Getting Ready to Write an Apple Mail.app Plug-in for Mac OS X
Blowing some dust off the old compiler this weekend… after about 8 years, I’m actually getting ready to write some real client-side software again. Just a personal project, for fun.
Nothing fancy, but I’ve decided to see if I can’t write some useful plug-ins for Mac OS X. In particular, I’m going to see if I can’t improve:
- Apple Address Book
- Apple Mail
I tend to joke with friends that when I went to business school, part of the admissions process was officially “turning in” my compiler. To show you how dated I am, the last serious Mac OS development I did was in Metrowerks Codewarrior.
Over my vacation in August, I went through Cocoa in a Nutshell from the O’Reilly series, just to refresh my memory. Even when I was on the WebObjects team at Apple, I primarily wrote framework code in Java, not Objective-C, so basically I’ve got to come up to speed again on:
- XCode 2.4
- Five versions of Mac OS X (the version I worked on became 10.0)
- Documented methods of extending Apple Address Book
- Undocumented methods of extending Apple Mail
I managed this weekend to get a sample plug-in for Apple Address Book working. This wasn’t a huge feat, really, since XCode includes a sample project for this as a default install, and it’s fairly trivial to customize the three Objective-C messages that define the functionality.
If you are looking for the documentation on extending Apple’s Mac OS X Address Book, check out:
Pretty basic really, although adding a contextual menu command for certain fields is hardly the best interface. I’ve been playing with Plaxo Toolbar for Mac, and trying to figure out how they inserted their drawer into the GUI.
Creating plug-ins for Apple Mail is much trickier, because it’s completely not supported or documented. Well, I shouldn’t say not supported… it’s not supported officially. However, Apple Mail does implement a plug-in architecture, and with a few quick setting changes, you can install a wide range of third party plug-ins.
Here are some cool links if you are interested:
- Demystifying Mail App Plugins. This blog post covers some high level tips and source code, in Python, to write a quick Mail.app plugin. Thanks to this post, I re-discovered class-dump, which lets you inspect the classes and methods for any Mac OS X application (very cool).
- Mail Plugin Template 1.0. Aaron Harnly, you are my hero. Aaron has posted an excellent XCode project template, with class-dump headers, for building your own Apple Mail plug-ins and installer scripts. He even answered a simple project question for me over email. Very cool.
- CocoaDev. This is a wiki site dedicated to Cocoa development. Aaron’s code pointed me here, since it features “Method Swizzling”. It’s a very sneaky feature of the Objective-C runtime, where you can effectively not only over-ride an method for an object you don’t own, but you can even replace the parent class method in applications that you don’t control! Read this for specifics (very cool if you’re into programming).
- Apple Mail Plug-Ins and Tools. A whole directory site of Apple Mail plug-ins.
- Apple Mail Plug-In Roundup. This post on The Unofficial Apple Weblog covered a lot of cool Mail.app plugins.
- Mail Act-On. Very cool Mail.app plug-in that lets you map individual rules to keyboard commands. My favorite Eudora feature, now on Mail.app
So far, I have an Apple Mail plug-in that compiles and loads correctly in Mail.app and logs data into the console. But I’m going to put that in the “W” column for this weekend, given my incredible level of rust around the gears.
I’m going to be flying to Omaha this week to visit the LinkedIn customer service team… I’m going to try and use the flight time to get a little bit more working.
My biggest question now is how far can I go in terms of influencing the Mail.app UI. I already know how to:
- Create a plug-in
- Insert menu commands and menus into the main application
- Create my own preferences panel & preferences file
- Create my own window
However, if I really want to integrate, I need to figure out how to:
- Add commands to existing contextual menus (I can’t find them in the NIB files anywhere)
- Add views/panes to the existing windows (ala a toolbar)
I haven’t found sample code that does either of the above yet, but I’m still looking.
All in all, it’s fun to be compiling again.