Как да кажа на ABPeoplePickerNavigationController да изброява само контакти, които имат имейл адрес?

Искам моите потребители да попълнят имейл поле, като изберат имейл на контакт от своите адресни книги. Не искам да превъртат всички контакти, чиито имейли не са зададени, затова искам да филтрирам тези, които имат имейл адреси.

Това е кодът, който съм написал досега. Мога да разбера кой има имейл адрес и кой не, но не можах да кажа на 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];

person aslisabanci    schedule 22.09.2012    source източник


Отговори (2)


Не вярвам, че има начин iOS да направи това филтриране. Правя го и в код. Обърнете внимание, че трябва да търсите всякакви имейл адреси - трябва да прегледате речника, който можете да получите. Работата с това със сигурност е PITA - правил съм го и преди - и трябва да внимавате да нямате изтичане на памет.

Това, което правя, е както предлагате - преглеждам сам всички контакти, след което показвам изглед с таблица и оставям след това да изберат имената на хората, които искат. Поддържам връзка, за да знам кой адрес е свързан с какво име, след което използвам системната имейл рамка и след това попълвам адресите за изпращане.

person David H    schedule 22.09.2012

Знам, че това е старо, но попаднах на това, докато проучвах свързана тема, така че реших да го актуализирам с моите открития.

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

    След като направите това, можете да създадете свой собствен изглед на таблица, като изброявате съответните подробности от това peopleWithEmails.

person Rob    schedule 11.08.2014
comment
Имайте предвид, че кодът под точка 2 е за iOS 6 и по-нови версии. Ако имате нужда от поддръжка за по-стари версии на iOS, не проверявайте за разрешение с ABAddressBookRequestAccessWithCompletion. - person Rob; 12.08.2014