6

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

这是我到目前为止写的代码。我可以弄清楚谁有电子邮件地址,谁没有,但我不能告诉他们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];
4

2 回答 2

15

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

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

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

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

    if ([peoplePickerController respondsToSelector:@selector(predicateForEnablingPerson)]) {
        peoplePickerController.predicateForEnablingPerson = [NSPredicate predicateWithFormat:@"emailAddresses.@count > 0"];
    }
    
  2. 如果你想过滤掉那些没有地址的条目,你必须为此提供你自己的用户界面(例如创建你自己的表格视图)。因此,首先,使用如下电子邮件地址构建您自己的联系人数组:

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

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

于 2014-08-11T23:30:04.713 回答
1

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

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

于 2012-09-22T22:24:49.377 回答