Search code examples
iosiphoneipadios7abaddressbook

application crashes at ABMultiValueRef


I am trying to access address book emails of iPad.

The part of code is :

ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, NULL);
ABRecordRef recordRef = ABAddressBookCopyDefaultSource(addressBookRef);
CFArrayRef arrayRef  = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBookRef, recordRef, kABPersonSortByFirstName);

for(int i = 0;i<ABAddressBookGetPersonCount(addressBookRef);i++)
{
      ABRecordRef ref = CFArrayGetValueAtIndex(arrayRef, i);
      ABMultiValueRef emails = ABRecordCopyValue(ref, kABPersonEmailProperty);
      .
      .
      .
      .

The crash is reproducible only on client iPad-Mini. we tried to reproduce crash but its not happening.

After analyzing the debug build we got to know that crash is happening in Line "ABMultiValueRef emails = ABRecordCopyValue(ref, kABPersonEmailProperty);". The crash is not happening every time. It happening once in 2-3 attempt to access addressBook emails. only for client.

My doubt is "ABRecordRef ref = CFArrayGetValueAtIndex(arrayRef, i);" may be nil or empty. But in what case this may be nil or empty?

can any one help me to know what may be the reason for crash.


Solution

  • The reason might be that ABAddressBookGetPersonCount returns the number of all people in the address book, whereas ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering returns all people of only 1 source, and their number might be different. Additionally I suggest that you check for errors like below. Of course you had also to CFRelease any returned CF object.

        CFErrorRef error = nil;
        ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, &error);
        if (addressBookRef != nil) {
            ABRecordRef recordRef = ABAddressBookCopyDefaultSource(addressBookRef);
            CFArrayRef arrayRef  = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBookRef, recordRef, kABPersonSortByFirstName);
            const unsigned int nrAllPeopleInSource = (unsigned int)CFArrayGetCount (arrayRef);
            if (arrayRef != nil) {
    //            for(int i = 0;i<ABAddressBookGetPersonCount(addressBookRef);i++)
                /*
                 ABAddressBookGetPersonCount returns the number of all people in the address book, whereas
                 ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering returns all people of only 1 source, and their number might be different.
                 */
                for(int i = 0;i<nrAllPeopleInSource;i++)
                {
                    ABRecordRef ref = CFArrayGetValueAtIndex(arrayRef, i);
                    ABMultiValueRef emails = ABRecordCopyValue(ref, kABPersonEmailProperty);
                    // ... further code
                }
            } else {
                // no person found
            }
        } else {
            // addressbook could not be opened, lookup error
        }