0

I'm trying to iterate through contacts (ABRecordRef's) in the address book(ABAddressBookRef). The app crashes when trying to copy kABPersonKindProperty property of the ref to check whether its a person contact or a company contact.

ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, nil);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
    if (granted) {
        ABRecordRef source = ABAddressBookCopyDefaultSource(addressBook);
        CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, source, kABPersonSortByFirstName);
        CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);

        NSMutableArray *contactsArray = [[NSMutableArray alloc] init];
        NSMutableArray *companyArray = [[NSMutableArray alloc] init];

        for( int i = 0 ; i < nPeople ; i++ ) {
            ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, i);
            if (ABRecordCopyValue(ref, kABPersonKindProperty) == kABPersonKindPerson) { // The app crashes on this line.
                MNContact *contact = [[MNContact alloc] initWithRecordReference:ref];
                [contactsArray addObject:contact];
            } else if (ABRecordCopyValue(ref, kABPersonKindProperty) == kABPersonKindOrganization) {
                MNCompany *company = [[MNCompany alloc] initWithRecordReference:ref];
                [companyArray addObject:company];
            }
        }

        self.hasLoadedContactsFromDevice = YES;
        _personContacts = [[NSArray alloc] initWithArray:contactsArray copyItems:YES];
        //            _companyContacts = [[NSArray alloc] initWithArray:companyArray copyItems:YES];
    } else {
        _personContacts = nil;
        _companyContacts= nil;
        self.hasLoadedContactsFromDevice = NO;
    }
    dispatch_semaphore_signal(self.sema);
});
dispatch_semaphore_wait(self.sema, DISPATCH_TIME_FOREVER);

If I print ref this is what I get

{
kCGImageSourceUseHardwareAcceleration = 1;
"kImageIOInfoHeader_alphaInfo" = 5;
"kImageIOInfoHeader_bitsPerComponent" = 8;
"kImageIOInfoHeader_bitsPerPixel" = 32;
"kImageIOInfoHeader_cacheImageBlocks" = 0;
"kImageIOInfoHeader_colorspaceModel" = 1;
"kImageIOInfoHeader_imageHeight" = 96;
"kImageIOInfoHeader_imageHeightOriginal" = 96;
"kImageIOInfoHeader_imageIndex" = 0;
"kImageIOInfoHeader_imageWidth" = 96;
"kImageIOInfoHeader_imageWidthOriginal" = 96;
"kImageIOInfoHeader_isLittleEndian" = 0;
"kImageIOInfoHeader_plugin" = "<CGImagePlus 0x165846f0>{w=96 h=96 prov=0x0 props=0x16584110 metadata=0x16584760}";
"kImageIOInfoHeader_pluginHandlesReMapping" = 1;
"kImageIOInfoHeader_rowBytes" = 384;
"kImageIOInfoHeader_session" = "<CGImageReadSessionRef 0x165844f0>{offset=3453 readref=0x165841f0}";
"kImageIOInfoHeader_supportsMultipleResolutions" = 1;
}

So my idea was to do a routine check whether the ref is an instance of class ABRecordRef.

Can anyone tell me what I'm doing wrong? Any suggestions are welcome.

Dunes Buggy
  • 1,779
  • 1
  • 21
  • 41

1 Answers1

0

The problem was with

ABRecordRef source = ABAddressBookCopyDefaultSource(addressBook);
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, source, kABPersonSortByFirstName);
CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);

Somehow the count of allPeople doesn't have the same number of elements (!= nPeople). Don't know why? But when I changed it to the following, everything worked fine.

CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople(addressBook);
CFIndex nPeople = CFArrayGetCount(allPeople);
Dunes Buggy
  • 1,779
  • 1
  • 21
  • 41