使用仅包含电子邮件的联系人显示ABAddressBook

时间:2012-08-16 20:01:53

标签: iphone objective-c ios

我想显示一个只显示带有电子邮件的联系人的ABAddressBook,所以我试过这样的事情:

    ABAddressBookRef addressBook = ABAddressBookCreate();
    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople( addressBook );
    CFIndex nPeople = ABAddressBookGetPersonCount( addressBook );

    for( CFIndex emailIndex = 0; emailIndex < nPeople; emailIndex++ ) {
        ABRecordRef person = CFArrayGetValueAtIndex( allPeople, emailIndex );
        ABMutableMultiValueRef emailRef=ABRecordCopyValue(person, kABPersonEmailProperty);
        int emailCount = ABMultiValueGetCount(emailRef);
        if(emailCount == 0) {
            ABAddressBookRemoveRecord(addressBook, person, NULL);
        }   
    }
    ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
    picker.addressBook = addressBook;
    picker.peoplePickerDelegate = self;
    [self presentModalViewController:picker animated:YES];

控制器显示,但显示所有联系人,如果我选择没有电子邮件的联系人,我会崩溃。如果我调用ABAddressBookSave(),它会删除所有带有电子邮件的联系人,但这是一个永久性更改,甚至会从系统联系人中删除它们。什么是正确的方法?

5 个答案:

答案 0 :(得分:1)

您可能需要构建一个包含电子邮件的联系人数组,然后将其显示在UITableViewController上。这是构建此类数组的一种方法:https://stackoverflow.com/a/13980023/745862。您可以使用ABPersonViewController或ABUnknownPersonViewController来显示联系人详细信息。

答案 1 :(得分:0)

您是否考虑过创建临时AddressBook并将其填入那些有电子邮件地址的联系人?

答案 2 :(得分:0)

您从AddressBook中删除了没有电子邮件地址的所有联系人,但最后没有保存AddressBook。从ABPeoplePickerNavigationController加载AddressBook时,之前的所有更改都将丢失! 试试这个:

if (ABAddressBookHasUnsavedChanges(addressBook))
    ABAddressBookSave(addressBook, NULL)
BTW,不要忘记CFRelease()地址簿,所有人和电子邮件地址。

答案 3 :(得分:0)

您是否尝试仅显示此类电子邮件值:

ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
picker.displayedProperties = @[@(kABPersonEmailProperty)];

也许那已经做到了,你想要什么?虽然没有测试它。

答案 4 :(得分:0)

从iOS 8开始,ABPeoplePickerNavigationController有一个属性可以解决您的问题:

@property (nonatomic,copy) predicateForEnablingPerson

Apple doc的代码示例:https://developer.apple.com/library/prerelease/ios/samplecode/PeoplePicker/Listings/PeoplePicker_AAPL_8or7_EmailPickerViewController_m.html

ABPeoplePickerNavigationController* abPicker = [ABPeoplePickerNavigationController new];
abPicker.peoplePickerDelegate = self;
//...
if ([abPicker respondsToSelector:@selector(setPredicateForEnablingPerson:)]){
    // The people picker will enable selection of persons that have at least one email address.
    abPicker.predicateForEnablingPerson = [NSPredicate predicateWithFormat:@"emailAddresses.@count > 0"];
}

请注意,在iOS9中不推荐使用ABPeoplePickerNavigationController,您可以使用与属性相同的新 CNContactPickerViewController

@property(nonatomic, copy) NSPredicate *predicateForEnablingContact

来自doc:

您可以为此属性设置一个值,以确定哪个联系人可以选择,例如emailAddresses。@ count&gt; 0表示启用所有具有电子邮件地址的联系人。如果没有为此属性设置谓词,则所有联系人都可以选择。