How do I tell ABPeoplePickerNavigationController a list of only contacts that have an email address?

I want my users to fill out an email field by selecting a contact email address from their address books. I don’t want them to scroll through all the contacts whose emails are not installed, so I want to filter out those that have email addresses.

This is the code that I have written so far. I can find out who has an email address and who does not, but I could not tell ABPeoplePickerNavigationController to list only the correct contacts. It’s impossible to achieve this, I mean, should I implement my own contact selection class 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]; 
+6
source share
2 answers

I don't believe there is a way to get iOS to do this filtering. I do this in code too. Please note that you need to search for all email addresses - you need to iterate over the dictionary that you can get. Working with this is PITA β€” I’ve done this before β€” and you have to be careful that there are no memory leaks.

What I do, just as you suggest, is to iterate over everything to contact me, then I pop the view with a table and then let me choose the names of the people they want. I support the association, so I know which address is associated with which name, then use the email system framework and then fill in the sending addresses.

+1
source

I know this is old, but I stumbled upon this while exploring a related topic, so I thought I was updating it with my findings.

  • While it does not filter the results, it is worth noting that iOS 8 has the function of disabling contacts that do not have an email address:

     peoplePickerController.predicateForEnablingPerson = [NSPredicate predicateWithFormat:@" emailAddresses.@count > 0"]; 

    You still see all the contacts, but at least those who do not have an email address are disabled. Obviously, if your minimum target OS is earlier than iOS 8, you would do it conditionally:

     if ([peoplePickerController respondsToSelector:@selector(predicateForEnablingPerson)]) { peoplePickerController.predicateForEnablingPerson = [NSPredicate predicateWithFormat:@" emailAddresses.@count > 0"]; } 
  • If you want to filter these entries without addresses, you will need to submit your own user interface (for example, create your own table view). So, firstly, create your own array of contacts with these email addresses:

     ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { if (granted) { NSArray *allPeople = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook)); NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id person, NSDictionary *bindings) { ABMultiValueRef emails = ABRecordCopyValue((__bridge ABRecordRef)person, kABPersonEmailProperty); NSInteger count = ABMultiValueGetCount(emails); CFRelease(emails); return count > 0; }]; NSArray *peopleWithEmails = [allPeople filteredArrayUsingPredicate:predicate]; // You now have an array of `ABRecordRef` associated with // those contacts with email addresses. You can use this as // the model backing your own table view, or populate your // own model. } else { NSLog(@"Access not granted"); if (error) { CFRelease(error); } } }); 

    By doing this, you can create your own tableview by specifying the appropriate data from this peopleWithEmails .

+15
source

Source: https://habr.com/ru/post/923074/


All Articles