Question

Please find below a code to import the iOS address book (lets assume we need to import - not just get a handle to it, for a specific need) --> some people using the app are complaining that only 15-20 of their addresses are being imported out of say 500. When one such person sent us their address book, I noticed besides 15-20 others are tagged as iCloud. This problem is not happening with everyone. Can someone tell us if we need to add special code for iCloud tagged entries? I don't think so, but confirming

- (void)getPersonOutOfAddressBook
{
    CFErrorRef error = NULL;
    __block BOOL accessGranted = NO;
    isAddressBookAccessGranted=NO;

    ABAddressBookRef addressBook = nil;

      addressBook = ABAddressBookCreateWithOptions(NULL, &error);

    if (ABAddressBookRequestAccessWithCompletion != NULL)
    {
        //-- we're on iOS 6
        if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusNotDetermined)
        {
            ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
                if (!granted)
                {
                    isAddressBookAccessGranted = NO;
                    UIAlertView * alertView = [[UIAlertView alloc]initWithTitle:NSLocalizedString(@"ERROR", nil) message:NSLocalizedString(@"ENABLE CONTACT ACCESS MESSAGE", nil) delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", nil)  otherButtonTitles:nil, nil];
                    [alertView performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:YES];

                }
                else
                {
                    isAddressBookAccessGranted = YES;

                    [self loadAddressBook:addressBook];
                }
            });
        }
        else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized)
        {
            isAddressBookAccessGranted = YES;

            {
                [self loadAddressBook:addressBook];
            }
        }
        else if(ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusDenied)
        {
            isAddressBookAccessGranted = NO;
            UIAlertView * alertView = [[UIAlertView alloc]initWithTitle:NSLocalizedString(@"ERROR", nil) message:NSLocalizedString(@"ENABLE CONTACT ACCESS MESSAGE", nil) delegate:nil cancelButtonTitle:NSLocalizedString(@"OK", nil) otherButtonTitles:nil, nil];
            [alertView show];
            // deleted some other code here - not related to addr book
        }
        else
        {
            //deleted some other code here - not related to addr book
        }
    }
    else
    {
        //-- we're on iOS 5 or older
        accessGranted = YES;
        isAddressBookAccessGranted = YES;
        [self loadAddressBook:addressBook];
    }
}

-(void) loadAddressBook:( ABAddressBookRef)currAddressBook
{
    if (currAddressBook != nil)
    {
        ABRecordRef source = ABAddressBookCopyDefaultSource(currAddressBook);
        NSArray *allContacts = (NSArray *)ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(currAddressBook, source, kABPersonSortByFirstName);
        NSUInteger i = 0;

       // if([AppDelegate sharedInstance].ABContactsArray!=nil)
            [mTempContactsArray removeAllObjects];

        for (i = 0; i < [allContacts count]; i++)
        {
            Person *person = [[[Person alloc] init] autorelease];

            ABRecordRef contactPerson = (__bridge ABRecordRef)allContacts[i];

            int recordID = ABRecordGetRecordID(contactPerson);
            person.recordID=[NSString stringWithFormat:@"%d",recordID];
            NSLog(@"RecordID = %d\n", recordID);

            NSString *firstName = ( NSString *)ABRecordCopyValue(contactPerson, kABPersonFirstNameProperty);
            NSLog(@"firstName = %@\n", firstName);

            NSString *lastName =  ( NSString *)ABRecordCopyValue(contactPerson, kABPersonLastNameProperty);
            NSLog(@"lastName = %@\n", lastName);

            NSString *fullName;

            if(!(firstName==nil) && !(lastName==nil))
                fullName= [NSString stringWithFormat:@"%@ %@", firstName, lastName];
            else if((firstName==nil) && (lastName==nil))
                fullName = @"";//[NSString stringWithFormat:NSLocalizedString(@"NO NAME STORED", nil)];
            else if (firstName==nil)
                fullName=[NSString stringWithFormat:@"%@", lastName];
            else if(lastName==nil)
                fullName=[NSString stringWithFormat:@"%@", firstName];

            person.firstName = firstName;
            person.lastName = lastName;
            person.fullName = fullName;

            person.imageData = ( NSData *) ABPersonCopyImageDataWithFormat(contactPerson, kABPersonImageFormatThumbnail);

            NSLog(@"imageData = %@\n", person.imageData);

            ABMultiValueRef phones = ABRecordCopyValue(contactPerson, kABPersonPhoneProperty);
            NSUInteger count=0;
            NSUInteger j = 0;
            person.numberDetailArray = [[[NSMutableArray alloc]init] autorelease] ;
            for (j = 0; j < ABMultiValueGetCount(phones); j++)
            {
                NSString *contactCategory;
                NSString *phone = (__bridge NSString *)ABMultiValueCopyValueAtIndex(phones, j);
                NSLog(@"phone number = %@\n", phone);

                NSString *phoneLabel = (__bridge NSString *) ABMultiValueCopyLabelAtIndex(phones, j);
                NSLog(@"phoneLabel = %@\n", phoneLabel);


                if([phoneLabel isEqualToString:(NSString *)kABPersonPhoneMobileLabel])
                {
                    contactCategory = @"mobile";
                    count++;
                }
                else if([phoneLabel isEqualToString:(NSString *)kABPersonPhoneIPhoneLabel])
                {
                    contactCategory = @"iPhone";
                    count++;
                }
                else if([phoneLabel isEqualToString:(NSString *)kABPersonPhoneMainLabel])
                {
                    contactCategory = @"main";
                    count++;
                }
                else if ([phoneLabel isEqualToString:@"_$!<Home>!$_"])
                {
                    contactCategory = @"home";
                    count++;
                }
                else if ([phoneLabel isEqualToString:@"_$!<Work>!$_"])
                {
                    contactCategory = @"work";
                    count++;
                }
                else
                {
                    contactCategory = @"other";
                    count++;
                }

                NumberInfo *numberInfo = [[[NumberInfo alloc]init] autorelease];
                numberInfo.contactNumberCategory = contactCategory;
                numberInfo.contactNumber = phone;

                numberInfo.parentID = person.recordID;

                //numberInfo.recordType = [NSNumber numberWithInt:kNumberRecord];
                [person.numberDetailArray addObject:numberInfo];
                if(phone)
                    CFRelease((__bridge CFTypeRef)(phone));
                if(phoneLabel)
                    CFRelease((__bridge CFStringRef)(phoneLabel));
            }

            person.phoneNumberCount= [NSString stringWithFormat:@"%d",(int)count];

            [mTempContactsArray addObject:person];
            if(phones)
                CFRelease(phones);
                    }
        if(source)
            CFRelease(source);

        NSLog(@"count=%d",[mTempContactsArray count]) ;
    }

    //-- after loading all the contacts, perform the table view operations on main thread
   // [self performSelectorOnMainThread:@selector(initializeSharedContactList) withObject:nil waitUntilDone:YES];
}
Was it helpful?

Solution

You need to iterate over all address book sources, not just the default one. Use ABAddressBookCopyArrayOfAllSources to get all sources, then iterate all sources and get contacts using ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering.

OTHER TIPS

Rather than iterating through sources, you can just use ABAddressBookCopyArrayOfAllPeople to pull everyone.

As a side note, when you do this you may get what appear to be duplicate entries. Contacts consolidates these into a unified contact page, but if you have Bob Smith synced from Facebook and iCloud, you'll have two ABRecords for Bob Smith - one from each source.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top