2011-03-01 15 views
6

Quiero buscar un número de teléfono específico en la libreta de direcciones del iPhone y luego recuperar el nombre del contacto. Actualmente estoy revisando todos los contactos y extrayendo las propiedades multivalo y comparando con el valor. Esto está tomando demasiado tiempo. He leído la guía de direcciones de Apple, y dicen:Buscar ABAddressbook iOS SDK

"lograr otros tipos de búsquedas, utilice la función de ABAddressBookCopyArrayOfAllPeople y luego filtrar los resultados utilizando el NSArray método filteredArrayUsingPredicate :."

¿Alguien me puede dar un ejemplo de cómo hacer exactamente eso?

Gracias.

+0

sería de ayuda. esta es mi respuesta sobre otra pregunta, http: // stackoverflow.com/questions/4272164/how-to-search-the-iphone-address-book-for-a-specific-phone-number/6953238 # 6953238 – ChangUZ

+0

Aquí está la forma más eficiente de hacerlo usando NSPredicate: http: // hesh .am/2012/10/lookup-a-contact-name-using-phone-number-in-abaddressbook/ –

Respuesta

9

Si desea hacer una búsqueda en los contactos con número de teléfono, entonces le diré una sugerencia.

1.Prepárese todos los contactos

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

2.Crear otra matriz (registros) de la matriz de contactos (thePeoples),

registros: [ record1, RECORD2, .... recordn]

registro: {name: "myContactName", phoneNumber: "1234567890"}

3. Busque el archivo mutableArray (registros) con el predicado.

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

NSArray * filteredArray = [records filteredArrayUsingPredicate:myPredicate]; 

Esto es solo un ejemplo simple para su solución, y recuerde que phoneNumber es un campo de valor múltiple. Por lo tanto, incluiremos una matriz como número de teléfono en la variable de clase de modelo.

+1

¿A qué te refieres con crear otra matriz a partir de la matriz de contactos? – AlBeebe

+1

¿Cómo funciona eso? [<__ NSCFType 0x6e1f220> valueForUndefinedKey:]: esta clase no es un valor clave que cumple con la codificación para el registro de clave. –

2

Use esto. este es mi código Make Array for searching.

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

Método de búsqueda. it (peopleWithNumber) sería más rápido que usar array (personas)

"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; 
} 
2

No puede utilizar un predicateWithFormat con una serie de ABRecordRef tipos opacos. Pero se puede usar predicateWithBlock:

[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; 
}]; 
3

El siguiente método devolverá una matriz que contiene todos los contactos que tienen el número de teléfono dado. Este método tardó 0.02 segundos en buscar 250 contactos en mi iPhone 5 con 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; 
} 
Cuestiones relacionadas