Friday, December 12, 2008

ABPerson flags

Mac OS X provides an API for reading and writing to the built in Address Book, but the documentation doesn't spell everything out as clearly as it should. Take the ABPerson Class Reference for example.

ABPerson actually represents any kind of contact in Address Book. A flag is used to determine if an ABPerson object represents a person or a company. Checking that flag should be simple, but the docs left me mystified at first.

ABPerson is basically an associative array, which makes it flexible and extensible. You read most properties of an ABPerson using the valueForProperty: method (defined in base class ABRecord). valueForProperty: takes an NSString* property name and returns the property value as an id (an untyped object pointer in Objective-C). The exact type returned by valueForProperty: varies depending on the property. The standard property names are defined in the Constants section for ABPerson. Unfortunately, the entry for kABPersonFlags property neglects to mention the return type.

Turns out that the kABPersonFlags property is an NSString* NSNumber* that contains an integer. The integer is used as a classic bit field; the second table in the ABPerson Constants section shows the bit mask constants used to read the individual flags in kABPersonFlags.

I whipped up a small Properties category for ABPerson to simplify reading the show as company or person flags:
// file "ABPerson+Properties.h"

#import <AddressBook/ABPerson.h>

@interface ABPerson (Properties)

-(int) flags;
-(BOOL) showAsCompany;
-(BOOL) showAsPerson;


And the module file:
// file "ABPerson+Properties.m"

#import "ABPerson+Properties.h"
#import <AddressBook/ABGlobals.h>

@implementation ABPerson (Properties)

-(int) flags {
return [[self valueForProperty: kABPersonFlags] intValue];

-(BOOL) showAsCompany {
return (self.flags & kABShowAsMask) == kABShowAsCompany;

-(BOOL) showAsPerson {
return (self.flags & kABShowAsMask) == kABShowAsPerson;

The flags method gets the kABPersonFlags property value and converts it to an integer while showAsCompany and showAsPerson do the bitmasking and comparisons.

No comments: