如何告诉ABPeoplePickerNavigationController仅列出具有电子邮件地址的联系人?

asl*_*nci 6 filter contacts addressbook ios

我希望我的用户通过从地址簿中选择联系人的电子邮件来填写电子邮件字段.我不希望他们滚动所有未设置电子邮件的联系人,所以我想过滤那些有电子邮件地址的联系人.

这是我到目前为止编写的代码.我可以弄清楚谁有一个电子邮件地址,谁没有,但我不能告诉ABPeoplePickerNavigationController只列出正确的联系人.是不可能实现这一点,我的意思是我必须使用表格视图实现我自己的联系人选择器类或这段代码有什么问题吗?

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];
Run Code Online (Sandbox Code Playgroud)

Rob*_*Rob 15

我知道这是旧的,但我在研究相关主题时偶然发现了这一点,所以我想我会用我的发现更新这个.

  1. 虽然它不会过滤结果,但值得注意的是,iOS 8具有禁用没有电子邮件地址的联系人的功能:

    peoplePickerController.predicateForEnablingPerson = [NSPredicate predicateWithFormat:@"emailAddresses.@count > 0"];
    
    Run Code Online (Sandbox Code Playgroud)

    您仍然可以看到所有联系人,但至少禁用那些没有电子邮件地址的联系人.显然,如果您的最低目标操作系统早于iOS 8,您可以有条件地执行上述操作:

    if ([peoplePickerController respondsToSelector:@selector(predicateForEnablingPerson)]) {
        peoplePickerController.predicateForEnablingPerson = [NSPredicate predicateWithFormat:@"emailAddresses.@count > 0"];
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 如果要过滤掉没有地址的条目,则必须为此提供自己的UI(例如,创建自己的tableview).首先,使用如下所示的电子邮件地址构建您自己的联系人数组:

    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);
            }
        }
    });
    
    Run Code Online (Sandbox Code Playgroud)

    完成后,您可以构建自己的tableview,列出相关的详细信息peopleWithEmails.


Dav*_*d H 1

我不相信有办法让 iOS 进行这种过滤。我也用代码来做。请注意,您需要查找各种电子邮件地址 - 您必须遍历可以获得的字典。使用这个肯定是一个 PITA - 我以前做过 - 并且你必须小心不要发生内存泄漏。

我所做的就是按照你的建议 - 自己遍历所有联系人,然后弹出一个带有表格的视图,然后选择他们想要的人员的姓名。我保持关联,以便知道哪个地址与哪个名称相关联,然后使用系统电子邮件框架,然后填充发送地址。