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!
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];
};