Adventures in the transition from C to Cocoa.

Tuesday, June 26, 2007

AddressBook

Ok, so I lied in my last post. I do have some GUI stuff in the works, but it's taking exceptionally long to screenshot the whole procedure. Sorry.

But, I do have one nugget of sample goodness for you: How to pull data out of the OS X AddressBook.

#import <Foundation/Foundation.h>
#import <AddressBook/ABAddressBook.h>
#import <AddressBook/ABMultiValue.h>

void printMultiValue(char *title,id prop, ABPerson *p)
{
int j,k;
ABMultiValue *multi = [p valueForProperty:prop];

if([multi count])
printf(" * %s:\n",title);

// sometimes we get NSDictionaries for values. These
// need to be handled differently (kABAddressProperty does this, for example)
if([[multi valueAtIndex:0] isKindOfClass:[NSDictionary class]] == YES)
{
for(k=0;k<[multi count];++k)
{
NSArray *keys, *values;
keys = [[multi valueAtIndex:k] allKeys];
values = [[multi valueAtIndex:k] allValues];

// get the dictionary name
printf(" * %s\n",
[[multi labelAtIndex:k] UTF8String]);

for(j=0;j<[keys count];++j)
{
printf(" * %s: %s\n",
[[keys objectAtIndex:j] UTF8String],
[[values objectAtIndex:j] UTF8String]);
}
}
}
else // normal handling
{
for(j=0;j<[multi count];++j)
{
printf(" * %s: %s\n",
//[[multi identifierAtIndex:j] UTF8String],
[[multi labelAtIndex:j] UTF8String],
[[multi valueAtIndex:j] UTF8String]);
}
}
}

int main()
{
int i;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
ABAddressBook *book = [ABAddressBook sharedAddressBook];

NSArray *people = [book people];

printf(" * People count: %i\n",[people count]);

for(i = 0;i<[people count];++i)
{
printf(" * Person %i\n",i);
ABPerson *p = [people objectAtIndex:i];
printf(" * First Name : %s\n",[[p valueForProperty:kABFirstNameProperty] UTF8String]);
printf(" * Middle Name: %s\n",[[p valueForProperty:kABMiddleNameProperty] UTF8String]);
printf(" * Last Name : %s\n",[[p valueForProperty:kABLastNameProperty] UTF8String]);
printf(" * Company : %s\n",[[p valueForProperty:kABOrganizationProperty] UTF8String]);

printMultiValue("E-Mail",kABEmailProperty,p);
printMultiValue("Phone",kABPhoneProperty,p);
printMultiValue("Address",kABAddressProperty,p);

printf(" * Note : %s\n",[[p valueForProperty:kABNoteProperty] UTF8String]);
}

[pool release];
return 0;
}


That's a pretty loaded example. And to compile it from the command line: gcc main.m -o main -framework Cocoa -framework AddressBook. Here we use an AutoreleasePool, which I haven't talk about yet, as well as some NSString data to present some meaningful output to the user.

This program will dump out a ton of information found inside your addressbook. There are a few more fields inside, but this is probably enough to get you started. I'll have to go through and document more sometime.

Categories