iOS 6 Address Book not working?

Keller picture Keller · Sep 20, 2012 · Viewed 23.6k times · Source

My method of programmatically retrieving e-mail addresses from the Address Book no longer seems to work on iOS 6 devices. It worked in iOS 5 and oddly, still works in the iOS 6 Simulator. Is there a new way to programmatically retrieve contacts from a users' Address Book?

ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);

self.contacts = [[NSMutableArray alloc] init];

int contactIndex = 0;
for (int i = 0; i < nPeople; i++) {
    // Get the next address book record.
    ABRecordRef record = CFArrayGetValueAtIndex(allPeople, i);        

    // Get array of email addresses from address book record.
    ABMultiValueRef emailMultiValue = ABRecordCopyValue(record, kABPersonEmailProperty);
    NSArray *emailArray = (__bridge_transfer NSArray *)ABMultiValueCopyArrayOfAllValues(emailMultiValue);

    [self.contacts addObject:emailArray];
}

To clarify, the above does not crash, it simply returns no results. ABAddressBookCopyArrayOfAllPeople is empty. Thanks!

Answer

Christopher Pickslay picture Christopher Pickslay · Sep 21, 2012

I created a helper class, AddressBookHelper, to handle backward compatibility. Here are the guts:

-(BOOL)isABAddressBookCreateWithOptionsAvailable {
    return &ABAddressBookCreateWithOptions != NULL;
}

-(void)loadContacts {
    ABAddressBookRef addressBook;
    if ([self isABAddressBookCreateWithOptionsAvailable]) {
        CFErrorRef error = nil;
        addressBook = ABAddressBookCreateWithOptions(NULL,&error);
        ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
            // callback can occur in background, address book must be accessed on thread it was created on
            dispatch_async(dispatch_get_main_queue(), ^{
                if (error) {
                    [self.delegate addressBookHelperError:self];
                } else if (!granted) {
                    [self.delegate addressBookHelperDeniedAcess:self];
                } else {
                    // access granted
                    AddressBookUpdated(addressBook, nil, self);
                    CFRelease(addressBook);
                }
            });
        });
    } else {
        // iOS 4/5
        addressBook = ABAddressBookCreate();
        AddressBookUpdated(addressBook, NULL, self);
        CFRelease(addressBook);
    }
}

void AddressBookUpdated(ABAddressBookRef addressBook, CFDictionaryRef info, void *context) {
    AddressBookHelper *helper = (AddressBookHelper *)context;
    ABAddressBookRevert(addressBook);
    CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);

    // process the contacts to return
    NSArray *contacts = ...    

    [[helper delegate] addressBookHelper:helper finishedLoading:contacts];
};