Поиск ABAddressbook iOS SDK - PullRequest
       13

Поиск ABAddressbook iOS SDK

6 голосов
/ 01 марта 2011

Я хочу найти в адресной книге iPhone определенный номер телефона, а затем получить имя контакта.В настоящее время я перебираю все контакты и извлекаю многозначные свойства и сравниваю их со значением.Это занимает слишком много времени.Я прочитал руководство по адресной книге Apple, и они говорят:

"выполните другие виды поиска, используйте функцию ABAddressBookCopyArrayOfAllPeople и затем отфильтруйте результаты с помощью метода NSArray FilterArrayUsingPredicate:."

Может кто-нибудь дать мне пример, как именно это сделать?

Спасибо.

Ответы [ 4 ]

9 голосов
/ 08 июня 2011

Если вы хотите выполнить поиск в контактах с номером телефона, то я скажу вам одно предложение.

1.Получить все контакты

NSArray *thePeoples = (NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);

2.Создать другой массив (записи) из массива контактов (thePeoples),

записи: [ запись1, запись2, .... записьN]

запись: {имя: "myContactName", PHONENUMBER: "1234567890"}

3. Ищите mutableArray (records) с предикатом.

NSPredicate * myPredicate = [NSPredicate predicateWithFormat:@"record.phoneNumber contains %@",string];

NSArray * filteredArray = [records filteredArrayUsingPredicate:myPredicate];

Это простой пример вашего решения, и помните, что phoneNumber - это многозначное поле. Поэтому мы включим массив в качестве номера телефона в переменную класса модели.

3 голосов
/ 16 января 2014

Следующий метод вернет массив, содержащий все контакты с указанным номером телефона.Этот метод занял 0,02 секунды для поиска 250 контактов на моем iPhone 5 под управлением iOS7.

#import <AddressBook/AddressBook.h>


-(NSArray *)contactsContainingPhoneNumber:(NSString *)phoneNumber {
    /*

     Returns an array of contacts that contain the phone number

     */

    // Remove non numeric characters from the phone number
    phoneNumber = [[phoneNumber componentsSeparatedByCharactersInSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]] componentsJoinedByString:@""];

    // Create a new address book object with data from the Address Book database
    CFErrorRef error = nil;
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
    if (!addressBook) {
        return [NSArray array];
    } else if (error) {
        CFRelease(addressBook);
        return [NSArray array];
    }

    // Requests access to address book data from the user
    ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {});

    // Build a predicate that searches for contacts that contain the phone number
    NSPredicate *predicate = [NSPredicate predicateWithBlock: ^(id record, NSDictionary *bindings) {
        ABMultiValueRef phoneNumbers = ABRecordCopyValue( (__bridge ABRecordRef)record, kABPersonPhoneProperty);
        BOOL result = NO;
        for (CFIndex i = 0; i < ABMultiValueGetCount(phoneNumbers); i++) {
            NSString *contactPhoneNumber = (__bridge_transfer NSString *) ABMultiValueCopyValueAtIndex(phoneNumbers, i);
            contactPhoneNumber = [[contactPhoneNumber componentsSeparatedByCharactersInSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]] componentsJoinedByString:@""];
            if ([contactPhoneNumber rangeOfString:phoneNumber].location != NSNotFound) {
                result = YES;
                break;
            }
        }
        CFRelease(phoneNumbers);
        return result;
    }];

    // Search the users contacts for contacts that contain the phone number
    NSArray *allPeople = (NSArray *)CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook));
    NSArray *filteredContacts = [allPeople filteredArrayUsingPredicate:predicate];
    CFRelease(addressBook);

    return filteredContacts;
}
2 голосов
/ 05 июля 2012

Вы не можете использовать предикатWithFormat с массивом непрозрачных типов ABRecordRef. Но вы можете использовать предикат с блоками:

[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
    ABRecordRef person=(__bridge ABRecordRef)evaluatedObject;
    CFTypeRef theProperty = ABRecordCopyValue(person, kABPersonPhoneProperty);
    NSArray *phones = (__bridge_transfer NSArray *) ABMultiValueCopyArrayOfAllValues(theProperty);
    CFRelease(theProperty);
    BOOL result=NO;
    for (NSString *value in phones) {
        if ([value rangeOfString:@"3"].location!=NSNotFound) {
            result=YES;
            break;
        }
    }
    return result;
}];
2 голосов
/ 08 августа 2011

Используйте это. это мой код Сделать массив для поиска.

        NSLog(@"=====Make People Array with Numbers. Start.");
        peopleWithNumber = [[NSMutableDictionary alloc] init];
        for (int i=0; i < [people count]; i++) {
            NSInteger phoneCount = [self phoneCountAtIndex:i];
            if (phoneCount != 0) {
                NSMutableArray *phoneNumbers = [[NSMutableArray alloc] init];
                for (int j=0 ; j < phoneCount ; j++) {
                    [phoneNumbers addObject:[self phoneNumberAtIndex:i phoneIndex:j]];
                }
                [peopleWithNumber addEntriesFromDictionary:
                 [NSDictionary dictionaryWithObjectsAndKeys:
                  [NSArray arrayWithArray:phoneNumbers],    [self fullNameAtIndex:i], nil]];
            }
        }
        NSLog(@"=====Make People Array with Numbers. End.\n");

Метод поиска. это (peopleWithNumber) будет быстрее, чем использование массива (people)

"NSArray * people = (NSArray *) ABAddressBookCopyArrayOfAllPeople (addressBook);"

- (NSArray *)searchNamesByNumber:(NSString *)number {

    NSString *predicateString = [NSString stringWithFormat:@"%@[SELF] contains '%@'",@"%@",number];
    NSPredicate *searchPredicate = [NSPredicate predicateWithFormat:predicateString,peopleWithNumber,number];
    NSArray *names = [[peopleWithNumber allKeys] filteredArrayUsingPredicate:searchPredicate];

    return names;
}
...