Importing data into AddressBook
XML to XML to vCard for Mac AddressBook.
Mac applications that work with people expect those people to be in your AddressBook. I've got a solution for syncing contacts with my phone, but that solution doesn't include support for AddressBook. Yesterday, I decided to fix that.
My ambitions don't extend to writing a full, round-trip syncing solution. Like the iCal data that I generate from the appointments in my phone, I'm perfectly content if the Mac application has “read only” access to the data.
What I needed to do was generate vCard data. Of course, not any vCard data, but the specific vCard data that AddressBook expects. A little more flexibility and a little less extensibility might have been good for that spec.
So I reverse engineered the particular flavor of vCard that AddressBook expects. Rather than trying to go directly from my data to that format, I crafted an intermediate XML vocabulary for the cards and a stylesheet to generate vCards from that.
Then I wrote the stylesheet that transforms my actual data (as expressed in RDF, so that I can take advantage of any inferred properties) to the vCard schema.
And it works. Sweet.
A few notes:
-
It is apparently a known bug that AddressBook ignores category information. I want to be able to select all the imported records so that I can delete them when I want to import new ones. To facilitate this, I added a “
hiptop-id
” attribute to thevcard
element. If you use it, then the stylesheet will generate a “Hiptop” URL for each card. The URL is useless, but the word “Hiptop” lets me use an AddressBook smart group to collect all the relevant vCards together. -
If you generate a
.vcf
file with Unix line ends, AddressBook botches the encoding. Make sure you generate “PC” line ends. -
It's impractical to generate base64 encoded photographs directly in XSLT. The vCard schema I constructed identifies photographs instead by URI. This is written to the
.vcf
file in what's presumably invalid vCard. I post-process the file with a Perl script that gets the URIs and base64 encodes them.
Share and enjoy.