Dan Wood: The Eponymous Weblog (Archives)

Dan Wood Dan Wood is co-owner of Karelia Software, creating programs for the Macintosh computer. He is the father of two kids, lives in the Bay Area of California USA, and prefers bicycles to cars. This site is his older weblog, which mostly covers geeky topics like Macs and Mac Programming. Go visit the current blog here.

Useful Tidbits and Egotistical Musings from Dan Wood

Categories: Business · Mac OS X · Cocoa Programming · General · All Categories

Sat, 06 Jan 2007

Collecting the user's email addresses

In a few places in Sandvox, we want the user to be able to specify his/her email address. So we make this easy by collecting a number of possible email addresses they might use and presenting them in a combo box. The user can then pick one of those, or hand-enter a different address if desired.

For today's episode, I thought I'd share the logic we use for collecting those addresses. We collect the possible addresses from three places, adding the addresses to a mutable set. We also try to determine the primary address, meaning the address most likely to be the one the user will choose.

NSMutableSet *emails = [NSMutableSet set];
NSString *primaryAddress = nil;

First off, we look in the address book's "me" card. The first address listed there will probably be the primary address.

ABMultiValue *meAddresses = [[[ABAddressBook sharedAddressBook] me]
    valueForProperty:kABEmailProperty];
int i;
for (i = 0 ; i < [meAddresses count] ; i++)
{
    NSString *thisAddress = [meAddresses valueAtIndex:i];
    [emails addObject:thisAddress];
    if (nil == primaryAddress)
    {
        primaryAddress = thisAddress;
    }
}

Next, we look in Apple Mail for some more addresses you might use, and merge them into the set. We look in all the active accounts and get the address or addresses associated with each. If we don't have a primary address yet, set it from the first address you find here.

NSMutableArray* mailAccounts
    = (NSMutableArray*) CFPreferencesCopyAppValue(
        (CFStringRef) @"MailAccounts",
        (CFStringRef) @"com.apple.mail");
[mailAccounts autorelease];
NSEnumerator *theEnum = [mailAccounts objectEnumerator];
NSDictionary *accountDict;

while (nil != (accountDict = [theEnum nextObject]) )
{
    BOOL isActive = YES;
    NSString *isActiveValue = [accountDict objectForKey:@"IsActive"];
    if (nil != isActiveValue)
    {
        isActive = [isActiveValue intValue];
    }
    if (isActive)
    {
        NSArray *emailAddresses
            = [accountDict objectForKey:@"EmailAddresses"];
        if ([emailAddresses count])
        {
            [emails addObjectsFromArray:emailAddresses];
            if (nil == primaryAddress)
            {
                primaryAddress = [emailAddresses objectAtIndex:0];
            }
        }
    }
}

The last place to look is your .mac account. If you have a .mac account, then you have a mac.com email address.

NSString *iToolsMember = [[NSUserDefaults standardUserDefaults]
    objectForKey:@"iToolsMember"];
if (nil != iToolsMember)
{
    NSString *iToolsAddr = [NSString stringWithFormat:
        @"%@@mac.com",iToolsMember];
    [emails addObject:iToolsAddr];
    if (nil == primaryAddress)
    {
        primaryAddress = iToolsAddr;
    }
}

That's all that you need. I suppose if I wanted I could also look in account lists for Entourage, Eudora, etc. but I don't have that information, and it might not be worth the trouble.