opening it up with Common Lisp
Book review: Darwinia
Summer reading: Spin
the Omnivoire's Delimma
the Golem's Eye
Apple's Address book provides a convenient system wide repository for contact information. Recent versions include the ability to connect contacts together by relations. For example:
One thing that Address book doesn't provide is a way of viewing these relationships. Today's task: build an application that reads the Address book database and produces a graph showing the relations.
My first thought was to do this entirely in Apple's Object Oriented Cocoa framework. It is, after all, the easiest and most supported way to work with Apple's code. A few things, however, stood in my way: Cocoa is a big framework and I'm still learning it; I'm not aware of any Cocoa graph manipulation library that is comparable to CL-Graph; and I'm not aware of any Cocoa graph layout mechanisms comparable to GraphViz. So my second thought was to dig up some old e-mails (and here) between Richard Cook and Gary Byers on the OpenMCL mailing list and use OpenMCL and its ObjectiveC Bridge. I also looked at Richard's code for his Address Book / Google Maps mashup (look towards the bottom of the page).
Step 1 : create the interface database that lets OpenMCL talk to the Address book framework.
Step 2: use the Address book interface and Lisp to build the graph and make a DOT file of it that GraphViz will like
Step 3: use GraphViz to make an image. Voila!
Now to go over the steps in a bit more detail.
Creating an Interface Database
The OpenMCL documentation (with special thanks to Dan Knapp) is very helpful and thorough. First one use FFIGEN to read the ObjectiveC framework and create FFI files and then one use the parse-standard-ffi-files in Lisp to create the CDB databases that OpenMCL likes. As long as you don't create the FFI files in one of your OpenMCL Lisp repositories and then try to create the CDBs in a different repository -- yes, I did that and it took me a long time to figure out why things weren't working! The error message was cryptic but it was a head banger once I figured it out. I did find that I needed to go through the AddressBook headers file by hand and do each one individually (but that may be due to user error on my part). My populate script is available if you're interested in seeing it.
Using the Address book from OpenMCL
Once again, most of the work had been done for me. I used the webkit example as a template along with advice from old e-mails on the OpenMCL mailing list. The final result is available. Once this file is in place (in the OpenMCL examples folder), all you need to do is (require 'addressbook).
The great thing about the ObjectiveC bridge in OpenMCL is that one can use Cocoa classes almost as easily as you can in ObjectiveC and XCode itself. Even better, you can develop interactively without that nasty edit/compile/run cycle. (Compilers have gotten faster but it's still an appreciable delay). Rather than go over the details here, I'll let the code do the talking.
Use GraphViz to layout the graph
and here it is:
By the way, if anyone knows how to tell GraphViz not to draw the edges and labels on top of one another, I'd appreciate it if they would tell me!
(Note that I found and fixed a minor display bug in CL-Graph while working on this example. If you want the edge labels to appear, you'll need to update).
Copyright -- Gary Warren King, 2004 - 2006