Search code examples
iosfiltercontactsaddressbook

How to tell ABPeoplePickerNavigationController to list only contacts that have an email address?


I want my users to fill an email field by selecting a contact's email from their address books. I don't want them to scroll all the contacts whose emails are not set, so I want to filter the ones that have email addresses.

This is the code I've written so far. I can figure out who has an email address and who has not but I couldn't tell the ABPeoplePickerNavigationController to list only the right contacts. Is it impossible to achieve this, I mean do I have to implement my own contact picker class by using a table view or is there something wrong with this piece of code?

ABAddressBookRef addressBook = ABAddressBookCreate();
NSArray *peopleList = (NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);
NSLog(@"%ld people exist in the addressBook", ABAddressBookGetPersonCount(addressBook));
for (id peopleRecord in peopleList) {
    ABMultiValueRef mv = ABRecordCopyValue((ABRecordRef)peopleRecord, kABPersonEmailProperty);
    CFIndex numberOfAddresses = ABMultiValueGetCount(mv);
    if(numberOfAddresses == 0) {
        CFErrorRef err;
        ABAddressBookRemoveRecord( addressBook, (ABRecordRef)peopleRecord, &err);
    }
}
[peopleList release];

NSLog(@"%ld people have an email", ABAddressBookGetPersonCount(addressBook));

ABPeoplePickerNavigationController *peoplePicker = [[ABPeoplePickerNavigationController alloc] init];
NSNumber* emailProp = [NSNumber numberWithInt:kABPersonEmailProperty];
[peoplePicker setAddressBook:addressBook];
peoplePicker.displayedProperties = [NSArray arrayWithObject:emailProp];
[peoplePicker setPeoplePickerDelegate:self];
[self presentModalViewController:peoplePicker animated:YES];

Solution

  • I do not believe there is a way to get iOS to do this filtering. I do it in code too. Note that you need to look for all kinds of email addresses - you have to iterate through the dictionary that you can get. Working with this is a PITA for sure - I've done it before - and you have to be careful to not have memory leaks.

    What I do is as you suggest - iterate through all contact myself, then I pop a view with a table and let then select the names of the people they want. I keep an association around so I know what address is associated with what name, then use the system email framework and then populate the send-to addresses.