Obtaining Specific ABSource from ABAddressBook in iOS 4+

iOS 4+ provides new API that allows one to select a specific ABSource from the ABAddressBook. This may be useful as some operations, e.g. creating an ABGroup, are not supported in some sources (i.e. Exchange).

"Not all source types support groups, more conspicuously, Exchange does not know anything about groups." - http://flavors.me/volonbolon#1a5/tumblr

Attached are functions that leverage the new API to obtain sources of specific types which may be used in calls to ABGroupCreateInSource().

#define CFRELEASE_AND_NIL(x) CFRelease(x); x=nil;
ABRecordRef sourceWithType (ABSourceType mySourceType)
{
    ABAddressBookRef addressBook = ABAddressBookCreate();
    CFArrayRef sources = ABAddressBookCopyArrayOfAllSources(addressBook);
    CFIndex sourceCount = CFArrayGetCount(sources);
    ABRecordRef resultSource = NULL;
    for (CFIndex i = 0 ; i < sourceCount; i++) {
        ABRecordRef currentSource = CFArrayGetValueAtIndex(sources, i);
        CFTypeRef sourceType = ABRecordCopyValue(currentSource, kABSourceTypeProperty);

        BOOL isMatch = mySourceType == [(NSNumber *)sourceType intValue];
        CFRELEASE_AND_NIL(sourceType);

        if (isMatch) {
            resultSource = currentSource;
            break;
        }
    }

    CFRELEASE_AND_NIL(addressBook);    
    CFRELEASE_AND_NIL(sources);

    return resultSource;
}

ABRecordRef localSource()
{
    return sourceWithType(kABSourceTypeLocal);
}

ABRecordRef exchangeSource()
{
    return sourceWithType(kABSourceTypeExchange);
}

ABRecordRef mobileMeSource()
{
    return sourceWithType(kABSourceTypeMobileMe);
}

Really wanna know how to create my own source.Just like the group Exchange create with which you dont need to edit the default source record but create own one,and what's most fantastic is,the addressbook will linked them together automatically.


Xyzzycoder-

Your solution works well if there is already a localSource, but just returns NULL if there isn't one.

Is there a way to, say, create an ABRecordRef for a localSource? I need to be able to store my contact to a non-synchronising source.

Cheers


The code has errors, thats why it always returns two, since the method: ABRecordGetRecordType is not a part of the ABSource. It only includes:

kABPersonType for person records kABGroupType for group records. kABSourceType for source records.

To figure out the right type you have to use: ABRecordCopyValue(source, kABSourceTypeProperty) instead! :) Works excellent on my iPhone with or without localSource.

Good luck!