IOS AddressBook is not fetching all the phone number from contact list
Asked Answered
S

3

5

I am using Addressbook in my IOS app to fetch the contact name and numbers, but a strange thing is happening that it is showing phone number of some of the contacts.

I was hoping it will show all the contact list with phone number.

so here is my code to fetch phone numbers:

-(void)getAddressbookData
{
    #if __IPHONE_OS_VERSION_MIN_REQUIRED < 60000
        ABAddressBookRef addressBook = ABAddressBookCreate();
    #else
        CFErrorRef *error = nil;
        ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
    #endif
        NSArray * people;
        BOOL accessGranted = [self __addressBookAccessStatus:addressBook];

        if (accessGranted)
        {
            people = (__bridge_transfer NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);
            // Do whatever you need with thePeople...
        }
        CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
        NSMutableArray *contactArray = [[NSMutableArray alloc] init];

        for (CFIndex i = 0; i < nPeople; i++)
        {
            ABRecordRef record = CFArrayGetValueAtIndex((__bridge CFArrayRef)(people), i);
            NSString *firstName = (__bridge NSString *)ABRecordCopyValue(record, kABPersonFirstNameProperty);
            NSString *lastName = (__bridge NSString *)ABRecordCopyValue(record, kABPersonLastNameProperty);
            NSString *fullName = nil;

            if (ABPersonGetCompositeNameFormat() == kABPersonCompositeNameFormatFirstNameFirst)
                fullName = [NSString stringWithFormat:@"%@ %@", firstName, lastName];
            else
                fullName = [NSString stringWithFormat:@"%@, %@", lastName, firstName];

            [contactArray addObject:fullName];

            //
            // Phone Numbers
            //
            ABMutableMultiValueRef phoneNumbers = ABRecordCopyValue(record, kABPersonPhoneProperty);
            CFIndex phoneNumberCount = ABMultiValueGetCount( phoneNumbers );

            NSMutableArray *numbersArray = [[NSMutableArray alloc] init];
            for ( CFIndex k=0; k<phoneNumberCount; k++ )
            {
                CFStringRef phoneNumberLabel = ABMultiValueCopyLabelAtIndex( phoneNumbers, k );
                CFStringRef phoneNumberValue = ABMultiValueCopyValueAtIndex( phoneNumbers, k );
                CFStringRef phoneNumberLocalizedLabel = ABAddressBookCopyLocalizedLabel( phoneNumberLabel );
                // converts "_$!<Work>!$_" to "work" and "_$!<Mobile>!$_" to "mobile"

                // Find the ones you want here
                //
               // NSLog(@"-----PHONE ENTRY -> name:%@ :  %@ : %@", fullName, phoneNumberLocalizedLabel, phoneNumberValue );
                [numbersArray addObject:CFBridgingRelease(phoneNumberValue)];

                CFRelease(phoneNumberLocalizedLabel);
                CFRelease(phoneNumberLabel);
                CFRelease(phoneNumberValue);
            }

           // NSLog(@"phone numbers %@", numbersArray);
            [contactDictionary setObject:numbersArray forKey:fullName];

            CFRelease(record);

        }

        selectContacts = contactArray;
       // NSLog(@"dictionary of array %@", contactDictionary);

        //NSLog(@"contacts count %d", [selectContacts count]);
    }

    -(BOOL)__addressBookAccessStatus:(ABAddressBookRef) addressBook
    {
        __block BOOL accessGranted = NO;

        if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6
            dispatch_semaphore_t sema = dispatch_semaphore_create(0);

            ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
                accessGranted = granted;
                dispatch_semaphore_signal(sema);
            });

            dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
            // dispatch_release(sema);
        }
        else { // we're on iOS 5 or older
            accessGranted = YES;
        }
        return accessGranted;
    }

so numbersArray is blank for some of the contacts I dont know why it is happening.

Sebastiansebastiano answered 17/5, 2013 at 10:51 Comment(0)
I
5

try this for phone no.

    ABAddressBookRef addressBook = ABAddressBookCreate();
    NSArray *people = (NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);
    for(id person in people){
    //fetch multiple phone nos.
        ABMultiValueRef multi = ABRecordCopyValue(person, kABPersonPhoneProperty);
        for (CFIndex j=0; j < ABMultiValueGetCount(multi); j++) {
            NSString* phone = (NSString*)ABMultiValueCopyValueAtIndex(multi, j);
            [numbersArray addObject:phone];
            [phone release];
        }
    }

and you have to alloc your array before you use. in viewDidLoad method write this for alloc array

           numbersArray=[[NSMutableArray alloc] init];
Interlingua answered 17/5, 2013 at 12:7 Comment(1)
It's good that you are releasing phone, but you're not releasing multi or people or addressBook. Run this through the static analyzer, and it will point out the leaks. If you replace the cast of (NSArray *) and (NSString *) with CFBridgingRelease, then ARC will take care of this. (Or if you use __bridging_transfer, like the OP, that will also do accomplish the same thing.) Needless to say, with iOS 9, the Contacts framework completely eliminates this problem, though obviously this question predated that framework.Spanker
R
1

I am using this code to access the mobile number from my address book and its working fine.

ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef allSources = ABAddressBookCopyArrayOfAllPeople( addressBook );
for (CFIndex i = 0; i < ABAddressBookGetPersonCount( addressBook ); i++)
    {
ABRecordRef aSource = CFArrayGetValueAtIndex(allSources,i);    
ABMultiValueRef phones =(NSString*)ABRecordCopyValue(aSource, kABPersonPhoneProperty);
        NSString* mobileLabel;

        for(CFIndex i = 0; i < ABMultiValueGetCount(phones); i++) {

            mobileLabel = (NSString*)ABMultiValueCopyLabelAtIndex(phones, i);

            if([mobileLabel isEqualToString:(NSString *)kABPersonPhoneMobileLabel])
            {
                home_mobile = [(NSString*)ABMultiValueCopyValueAtIndex(phones, i) retain];

            }

            if ([mobileLabel isEqualToString:(NSString*)kABPersonPhoneIPhoneLabel])
            {
                basic_mobile = [(NSString*)ABMultiValueCopyValueAtIndex(phones, i)retain];


            }
            if([mobileLabel isEqualToString:(NSString *)kABPersonPhoneMainLabel])
            {
                work_mobile = [(NSString*)ABMultiValueCopyValueAtIndex(phones, i)retain];

            }
        }

You can try this.

Reuben answered 17/5, 2013 at 12:14 Comment(0)
P
1

Here's the Swift version of @Samir's answer which worked for me.

var allNumbers: [AnyObject] = []
let adbk : ABAddressBook? = ABAddressBookCreateWithOptions(nil, nil).takeRetainedValue()
let people = ABAddressBookCopyArrayOfAllPeople(adbk).takeRetainedValue() as NSArray as [ABRecord]
for person in people {
    var phones: ABMultiValueRef = ABRecordCopyValue(person, kABPersonPhoneProperty).takeRetainedValue()
    for j in 0..<ABMultiValueGetCount(phones) {
        var phone: String = ABMultiValueCopyValueAtIndex(phones, j).takeRetainedValue() as String
        allNumbers.append(phone)
    }
}
println(allNumbers)
Politicize answered 4/11, 2014 at 1:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.