0

I need to find a contact in AdreesBook in order to add a new social network. Sometimes I have to find a contact by its phones and emails or by its phones, firstName and lastName, is there any kind of query to get ABRecordRef contact instead of doing whiles?

Many of my users have more than 1000 contacts and I need to update many of them, so it is not efficient if my only solution is to do so many whiles...

Any idea??

Thanks!

Aarranz
  • 461
  • 6
  • 20

1 Answers1

3

Below is method which may help you to get the Contact details using phone number. For that its used kABPersonPhoneProperty, same way you can write another functions for searching email and name:

  • For email, use a property : kABPersonEmailProperty
  • For First Name : kABPersonFirstNameProperty

For more details, go through: ABPerson Reference

Hope this helps.

#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;
}
Mrunal
  • 13,982
  • 6
  • 52
  • 96
  • Thanks a lot! i'm going to try it. This only works if I have only one phoneNumber correct? Can I use an array in rangeOfString? – Aarranz Jan 21 '15 at 15:23
  • This is the method, I have used for searching Mobile Number as string. For your case, you might require to modify the method a bit, and also looping the function if its array of numbers. – Mrunal Jan 21 '15 at 15:26
  • At least first, try with a single contact number search. Then gradually update code. – Mrunal Jan 21 '15 at 15:27