2011-03-01 15 views
6

Desidero effettuare una ricerca nella rubrica di iPhone per un numero di telefono specifico, quindi recuperare il nome del contatto. Attualmente sto eseguendo il ciclo di tutti i contatti e estraendo le proprietà multivalore e confrontandole con il valore. Questo sta prendendo troppo tempo. Ho letto la guida rubrica di Apple, e dicono:Cerca ABAddressbook iOS SDK

"compiere altri tipi di ricerche, utilizzare la funzione di ABAddressBookCopyArrayOfAllPeople e poi filtrare i risultati utilizzando il NSArray metodo filteredArrayUsingPredicate :."

Qualcuno può darmi un esempio su come farlo esattamente?

Grazie.

+0

sarebbe di aiuto. questa è la mia risposta a un'altra domanda, http: // stackoverflow.it/questions/4272164/how-to-search-the-iphone-indirizzo-libro-per-un-specifico-numero-telefono/6953238 # 6953238 – ChangUZ

+0

Ecco il modo più efficiente per farlo usando NSPredicate: http: // hesh .am/2012/10/lookup-a-contact-name-using-phone-number-in-abaddressbook/ –

risposta

9

Se si desidera effettuare una ricerca nei contatti con il numero di telefono, quindi vi dirò un suggerimento.

1.Get tutti i contatti

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

2.Creare un altro array (record) dal contatti matrice (thePeoples),

record: [ RECORD1, RECORD2, .... recordN]

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

3. Ricercare il mutableArray (record) con predicato.

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

NSArray * filteredArray = [records filteredArrayUsingPredicate:myPredicate]; 

Questo è solo un semplice esempio della soluzione e ricordare phoneNumber è un campo multiValue. Quindi includeremo un array come numero di telefono nella variabile della classe del modello.

+1

Cosa intendi con la creazione di un altro array dall'array di contatti? – AlBeebe

+1

Come funziona? [<__ NSCFType 0x6e1f220> valueForUndefinedKey:]: questa classe non è un valore chiave conforme alla codifica per il record della chiave. –

2

Utilizzare questo. questo è il mio codice Crea array per la ricerca.

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

Metodo di ricerca. it (peopleWithNumber) sarebbe più veloce dell'utilizzo di array (persone)

"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

Non si può usare un predicateWithFormat con una serie di ABRecordRef tipi opachi. Ma è possibile utilizzare 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

Il seguente metodo restituisce un array che contiene tutti i contatti che hanno il numero di telefono indicato. Questo metodo ha impiegato 0,02 secondi per cercare 250 contatti sul mio 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; 
}