0

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.

Raju
  • 441
  • 1
  • 6
  • 17

1 Answers1

0

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
    }
Reinhard Männer
  • 14,022
  • 5
  • 54
  • 116
  • Can u please tell in what scenario can we reproduce crash? because its not happening on our device? or how can we make "ABRecordRef" nil? – Raju Sep 09 '14 at 05:59
  • To reproduce the crash on your device, it should be enough to add a further source to your addressbook that contains at least one person. Common sources are iCloud or an additional CardDAV server. I guess your default source is iCloud. An additional CardDAV server can be e.g. created for testing purposes using the OSX server. – Reinhard Männer Sep 09 '14 at 06:18
  • can u please tell, if "ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering" returns all people of only 1 source.. How to get all people in all source..? – Raju Sep 10 '14 at 10:24
  • 1
    You could use ABAddressBookCopyArrayOfAllPeople, but than you had to sort them by your own. One more thing: You could also enable a further CardDAV server, if you have e.g. the Facebook app installed, and you switch in the systems settings / Facebook contacts to ON. – Reinhard Männer Sep 10 '14 at 13:21