dormitkon
dormitkon

Reputation: 2526

Get contacts list in iOS8, crashes the app

Getting contacts in iOS8 (iPhone 5s) causes crash randomly. Crash details: http://hastebin.com/ukihinucaf.md

At line:

    ABMultiValueRef multiEmails = ABRecordCopyValue(person, kABPersonEmailProperty);

Here is the whole function:

-(NSArray *) getAllContacts
{

    CFErrorRef *error = nil;

    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);

    __block BOOL accessGranted = NO;
    if (ABAddressBookRequestAccessWithCompletion != NULL) {
        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);

    }
    else {
        accessGranted = YES;
    }

    if (accessGranted) {

        ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
        ABRecordRef source = ABAddressBookCopyDefaultSource(addressBook);
        CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, source, kABPersonSortByFirstName);
        CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);
        NSMutableArray* items = [NSMutableArray arrayWithCapacity:nPeople];
        for (int i = 0; i < nPeople; i++)
        {

            ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);

            //get Contact email

            ABMultiValueRef multiEmails = ABRecordCopyValue(person, kABPersonEmailProperty);

            for (CFIndex j=0; j<ABMultiValueGetCount(multiEmails); j++) {
                CFStringRef contactEmailRef = ABMultiValueCopyValueAtIndex(multiEmails, j);
                NSString *contactEmail = (__bridge NSString *)contactEmailRef;

                [items addObject:contactEmail];
            }

        }
        return items;

    } else {
        NSLog(@"Cannot fetch Contacts :( ");
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Fetch failed" message:@"Can't fetch your contacts." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
        [alert show];
        return nil;

    }
}

Anybody knows what can be a problem?

Upvotes: 1

Views: 1631

Answers (2)

Rich Fox
Rich Fox

Reputation: 2194

ABAddressBookCreateWithOptions(NULL, error);

Should be this

CFErrorRef error = NULL;
ABAddressBookCreateWithOptions(NULL, &error);

Upvotes: 2

Rob
Rob

Reputation: 437412

You are retrieving ABAddressBookGetPersonCount (the count of all the people in all of the sources, not just the count of people in the default source), and using that as the upper threshold when you're iterating through the array. But the array doesn't contain all of the people in the address book, but rather only those in the default source. Thus, you may exceed the number of items in the array.

I would suggest using CFArrayGetCount rather than ABAddressBookGetPersonCount.

Upvotes: 2

Related Questions