My favourite Tiger feature

The title here is a bit misleading. My favourite Tiger feature really is Spotlight. But I want to talk about something really cool that nobody is talking about:

kABWithinIntervalAroundTodayYearless

kABWhat?

Last year, I posted code for year-insensitive date-sorting, mentioning I was working on a birthday-tracking application. At the time, writing such an application would have all sorts of junk code. But Mac OS X Tiger is full of great developer features, including several handy additions to Addressbook.framework. ABTypedefs.h contains the following:

#if MAC_OS_X_VERSION_10_4 < = MAC_OS_X_VERSION_MAX_ALLOWED
        kABDoesNotContainSubString,
        kABDoesNotContainSubStringCaseInsensitive,
        kABNotEqualCaseInsensitive,
        kABSuffixMatch,
        kABSuffixMatchCaseInsensitive,
        kABWithinIntervalAroundToday,
        kABWithinIntervalAroundTodayYearless,
        kABNotWithinIntervalAroundToday,
        kABNotWithinIntervalAroundTodayYearless,
        kABWithinIntervalFromToday,
        kABWithinIntervalFromTodayYearless,
        kABNotWithinIntervalFromToday,
        kABNotWithinIntervalFromTodayYearless
#endif

Now, you can find everybody whose birthday, is, say, January 10, regardless of what year they were born in. To find everybody whose birthday is today, you need just three lines of code:

AB = [ABAddressBook sharedAddressBook];

peopleWithBirthdays =
[ABPerson searchElementForProperty:kABBirthdayProperty
                             label:nil
                               key:nil
                             value:[NSNumber numberWithInt:60*60*24]
                       comparison:kABWithinIntervalAroundTodayYearless];

peopleFound = [AB recordsMatchingSearchElement:peopleWithBirthdays];

Now you’ve got a list of people, but they aren’t ordered — perhaps they’re in the order you added them to the Address Book. The sort is quick and easy:

sortedPeopleFound = [peopleFound sortedArrayUsingFunction:personSortByBirthday context:NULL];

To print out the list, just create an NSEnumerator, and loop over it:

peopleEnumerator = [sortedPeopleFound objectEnumerator];
while (person = [peopleEnumerator nextObject]) {
    printf("%s: %s %s\n",
           [[[person valueForProperty:kABBirthdayProperty]
             descriptionWithCalendarFormat:@"%B %d"] UTF8String],
           [[person valueForProperty:kABFirstNameProperty] UTF8String],
           [[person valueForProperty:kABLastNameProperty] UTF8String]);
}

I’ve put the whole thing together for you to download. To compile it, do this:

gcc -framework Foundation -framework AddressBook bdays.m -o bdays

Now, install and run it:

sudo mkdir -p /usr/local/bin
sudo cp bdays /usr/local/bin
/usr/local/bin/bdays

To see birthdays within 5 days of today:

/usr/local/bin/bdays 5

Leave a Reply

Your email address will not be published. Required fields are marked *