1

Phone number getting like this. Phone ABMultiValueRef 0x17674380 with 1 value(s) 0: $!!$ (0x176740e0) - 7124779070 (0x176742a0)

How to get this number"7124779070" from the above line.

I'm using this code for ios 7.Is it correct or wrong ,Please sugggest me.

 int i;
    ABAddressBookRef contactBook = ABAddressBookCreateWithOptions(NULL, NULL);
    NSMutableArray *allData = ( NSMutableArray *)(ABAddressBookCopyArrayOfAllPeople(contactBook));
    CFIndex contactNum = CFArrayGetCount((__bridge CFArrayRef)(allData));

    for (i = 0; i < contactNum; i++)
    {
        ABRecordRef ref = CFArrayGetValueAtIndex((__bridge CFMutableArrayRef)(allData), i);
        NSString*  firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
        NSString* lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
        NSString*  phonesNum = ABRecordCopyValue(ref, kABPersonPhoneProperty);

        // Remove all formatting symbols that might be in both phone number being compared
        NSCharacterSet *toExclude = [NSCharacterSet characterSetWithCharactersInString:@"/.()- "];
        phonesNum = [[phonesNum componentsSeparatedByCharactersInSet:toExclude] componentsJoinedByString: @""];
    NSString *phoneNumber = [[phonesNum componentsSeparatedByCharactersInSet:toExclude] componentsJoinedByString: @""];



        NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
        if (firstName!=nil)
        {
            [dic setObject:(__bridge id)(firstName) forKey:@"firstName"];

        }
        if (lastName !=nil) {
            [dic setObject:(__bridge id)(lastName) forKey:@"lastName"];

        }
        if (phonesNum!=nil) {
            [dic setObject:(__bridge id)(phonesNum) forKey:@"phonesNum"];
        }

        [arr_Contacts addObject:dic];

        NSLog(@"First name %@", firstName);
        NSLog(@"Last Name %@", lastName);
        NSLog(@"Phone %@", phonesNum);
    }
Ravikumar
  • 85
  • 1
  • 16
  • Do you want only the first phone number or all of them? – Rob Sep 06 '14 at 12:56
  • 1
    Have you gone through the [Address Book Programming Guide](https://developer.apple.com/Library/ios/documentation/ContactData/Conceptual/AddressBookProgrammingGuideforiPhone/Introduction.html)? You should, if you haven't. Even though it does not answer most of the issues, what you are asking is not at all basic coding. You can copy and paste the code in answers, but that will leave you with even more issues (and confusion) if you do it blindly. – n00bProgrammer Sep 06 '14 at 13:36
  • Possible duplicate of http://stackoverflow.com/a/23418263/1271826 – Rob Sep 06 '14 at 13:54

2 Answers2

1

First, request permission:

ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();

if (status != kABAuthorizationStatusAuthorized && status != kABAuthorizationStatusNotDetermined) {
    // tell user to enable contacts in privacy settings
    NSLog(@"You previously denied access: You must enable access to contacts in settings");

    return;
}

CFErrorRef error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
if (!addressBook) {
    NSLog(@"ABAddressBookCreateWithOptions error: %@", CFBridgingRelease(error));
    return;
}

ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
    if (error) {
        NSLog(@"ABAddressBookRequestAccessWithCompletion error: %@", CFBridgingRelease(error));
    }

    if (granted) {
        [self getContacts:addressBook];
    } else {
        // tell user to enable contacts in privacy settings
        NSLog(@"You just denied access: You must enable access to contacts in settings");
    }

    CFRelease(addressBook);
});

Second, to retrieve the phone numbers, use ABMultiValueCopyValueAtIndex:

- (void)getContacts:(ABAddressBookRef)addressBook
{
    NSArray *allData = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook));
    NSInteger contactCount = [allData count];

    for (int i = 0; i < contactCount; i++) {
        ABRecordRef person = CFArrayGetValueAtIndex((__bridge CFArrayRef)allData, i);

        NSString *firstName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
        NSString *lastName  = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty));

        NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
        if (firstName) {
            dictionary[@"firstName"] = firstName;
        }
        if (lastName) {
            dictionary[@"lastName"]  = lastName;
        }

        ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
        CFIndex phoneNumberCount = ABMultiValueGetCount(phones);

        if (phoneNumberCount > 0) {
            NSString *phone = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phones, 0));
            dictionary[@"phone"] = phone;
        }

        // or if you wanted to iterate through all of them, you could do something like:
        //
        // for (int j = 0; j < phoneNumberCount; j++) {
        //      NSString *phone = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phones, j));
        //
        //     // do something with `phone`
        // }

        if (phones) {
            CFRelease(phones);
        }

        [arr_Contacts addObject:dictionary];
    }
}

A couple of additional issues addressed above:

  1. The ABAddressBookCreateWithOptions does not return a mutable array. It's an immutable array. Replace all of those mutable references with immutable.

  2. You must honor the Create Rule, namely that you're responsible for releasing any object returned from a Core Foundation method with either Create or Copy in its name. If the object supports toll-free bridging (e.g. the array of contacts, the first name string, the last name string, etc.), you can transfer ownership to ARC with CFBridgingRelease or __bridge_transfer. If the object doesn't support toll-free bridging (such as the phones or addressBook objects, above), then you must explicitly call CFRelease for the object in question.

    Make sure to run your code through the static analyzer (shift+command+B, or choose "Analyze" from Xcode's "Product" menu), and it will identify these sorts of issues for you.

  3. If a function, such as ABAddressBookCreateWithOptions offers an error parameter, you should avail yourself of it. I illustrate the proper use of the CFErrorRef object above.

Community
  • 1
  • 1
Rob
  • 415,655
  • 72
  • 787
  • 1,044
0

What do you recive in console from Phone %@ NSLog ? if Phone ABMultiValueRef 0x17674380 with 1 value(s) 0: $!!$ (0x176740e0) - 7124779070 (0x176742a0)just substring after '-'

NSString *myString = @"Phone ABMultiValueRef 0x17674380 with 1 value(s) 0: $!!$ (0x176740e0) - 7124779070 (0x176742a0)";
NSArray *myArray = [myString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"-"]];    

and this is my method to get phone's

   - (void) getContacts
    {
    NSMutableDictionary *response = [[NSMutableDictionary alloc] init];

    ABAddressBookRef contactBook = ABAddressBookCreateWithOptions(NULL, NULL);
    arr_Contacts = [[NSMutableArray alloc] init];
    ABAddressBookRef allPeople = contactBook;
    CFArrayRef allContacts = ABAddressBookCopyArrayOfAllPeople(allPeople);
    CFIndex numberOfContacts  = ABAddressBookGetPersonCount(allPeople);
    NSLog(@"contact == %@",allContacts);


    NSLog(@"numberOfContacts------------------------------------%ld",numberOfContacts);

    for(int i = 0; i < numberOfContacts; i++){
        NSString* name = @"";
        NSString* phone = @"";
        NSString* email = @"";

        ABRecordRef aPerson = CFArrayGetValueAtIndex(allContacts, i);
        ABMultiValueRef fnameProperty = ABRecordCopyValue(aPerson, kABPersonFirstNameProperty);
        ABMultiValueRef lnameProperty = ABRecordCopyValue(aPerson, kABPersonLastNameProperty);

        ABMultiValueRef phoneProperty = ABRecordCopyValue(aPerson, kABPersonPhoneProperty);\
        ABMultiValueRef emailProperty = ABRecordCopyValue(aPerson, kABPersonEmailProperty);

        NSArray *emailArray = (__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(emailProperty);
        NSArray *phoneArray = (__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(phoneProperty);


        if (fnameProperty != nil) {
            name = [NSString stringWithFormat:@"%@", fnameProperty];
        }
        if (lnameProperty != nil) {
            name = [name stringByAppendingString:[NSString stringWithFormat:@" %@", lnameProperty]];
        }

        if ([phoneArray count] > 0) {
            if ([phoneArray count] > 1) {
                for (int i = 0; i < [phoneArray count]; i++) {
                    phone = [phone stringByAppendingString:[NSString stringWithFormat:@"%@, ", [phoneArray objectAtIndex:i]]];
                }
            }else {
                phone = [NSString stringWithFormat:@"%@", [phoneArray objectAtIndex:0]];
            }
        }

        if ([emailArray count] > 0) {
            if ([emailArray count] > 1) {
                for (int i = 0; i < [emailArray count]; i++) {
                    email = [email stringByAppendingString:[NSString stringWithFormat:@"%@\n", [emailArray objectAtIndex:i]]];
                }
            }else {
                email = [NSString stringWithFormat:@"%@", [emailArray objectAtIndex:0]];
            }
        }
        NSLog(@"NAME : %@",name);
        NSLog(@"PHONE: %@",phone);
        NSLog(@"EMAIL: %@",email);
        NSLog(@"\n");
        [response setObject:name forKey:@"name"];
        [response setObject:phone forKey:@"phone"];
        [response setObject:email forKey:@"email"];

      [arr_Contacts addObject:response];
    }

    }

Cheers

Michal Rogowski
  • 431
  • 3
  • 18