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

前端 未结 2 1016
心在旅途
心在旅途 2021-01-18 13:18

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

相关标签:
2条回答
  • 2021-01-18 14:03

    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.

    0 讨论(0)
  • 2021-01-18 14:05

    I know this is old, but I stumbled across this while researching a related topic, so I thought I'd update this with my findings.

    1. While it doesn't filter the results, it's worth noting that iOS 8 has a feature for disabling contacts that don't have an email address:

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

      You still see all of the contacts, but at least those without an email address are disabled. Obviously, if your minimum target OS predates iOS 8, you'd do the above conditionally:

      if ([peoplePickerController respondsToSelector:@selector(predicateForEnablingPerson)]) {
          peoplePickerController.predicateForEnablingPerson = [NSPredicate predicateWithFormat:@"emailAddresses.@count > 0"];
      }
      
    2. If you want to filter out those entries without addresses, you'll have to present your own UI (e.g. create your own tableview) for this. So, first, build your own array of contacts with email addresses like so:

      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);
              }
          }
      });
      

      Having done that, you can then build your own tableview listing the relevant details from that peopleWithEmails.

    0 讨论(0)
提交回复
热议问题