ABAddressBookCopyArrayOfAllPeople and ABAddressBookGetPersonCount return different sizes

自古美人都是妖i 提交于 2019-11-30 14:11:37

ABAddressBookGetPersonCount And ABAddressBookCopyArrayOfAllPeople gives different arrays.

ABAddressBookGetPersonCount - Returns the number of person records in an address book. ABAddressBookCopyArrayOfAllPeople - Returns all the person records in an address book.

So some times same person may have extra records. That's why you may getting different sizes.

I meet this problem today. My app also crashes in some special iDevices.

code:

    ABRecordRef source = ABAddressBookCopyDefaultSource(addressBook);
    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, source, kABPersonSortByLastName);

    CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);

    for (int i = 0; i < nPeople; i++) {
        ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);
        // more thing with `person`
    }

But it will crash sometimes. Adding some breakpoints I found that allPeople's count is less than nPeople.

By googling, I found this article. I found that maybe there's something wrong with ABAddressBookCopyDefaultSource. Here I got the default source, I have to got all sources instead.

code:

CFArrayRef sources = ABAddressBookCopyArrayOfAllSources(addressBook);

CFIndex sourceCount = CFArrayGetCount(sources);

for (CFIndex i = 0; i < sourceCount; i++) {
    ABRecordRef currentSource = CFArrayGetValueAtIndex(source, i);
    int sourceType = [(__bridge NSNumber *)ABRecordCopyValue(currentSource, kABSourceTypeProperty) intValue];
    switch (sourceType) {

        case kABSourceTypeCardDAV:
            NSLog(@"kABSourceTypeCardDAV");
            break;

        case kABSourceTypeCardDAVSearch:
            NSLog(@"kABSourceTypeCardDAVSearch");
            break;

        case kABSourceTypeExchange:
            NSLog(@"kABSourceTypeExchange");
            break;

        case kABSourceTypeExchangeGAL:
            NSLog(@"kABSourceTypeExchangeGAL");
            break;

        case kABSourceTypeLDAP:
            NSLog(@"kABSourceTypeLDAP");
            break;

        case kABSourceTypeLocal:
            NSLog(@"kABSourceTypeLocal");
            break;

        case kABSourceTypeMobileMe:
            NSLog(@"kABSourceTypeMobileMe");
            break;

        default:
            break;
    }
    CFArrayRef allPeopleInSource = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, currentSource, kABPersonSortByLastName);
    NSLog(@"Count of allPeopleInSource: %i", CFArrayGetCount(allPeopleInSource));
}

Then I got

    kABSourceTypeCardDAV
    Count of allPeopleInSource: 7

which means there is only one source and only 7 records in that source.

But in my address book, I have 79 contacts!

Then I made a mistake. I passed the sources to ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering, just like this:

    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, sources, kABPersonSortByLastName);

How many members in allPeople?

72!!!

Exactly the count of records which are not in sources.

I passed a CFArrayRef to ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering as the second parameter, which expects a ABRecordRef. What if I pass nil?

Finally, I got the codes:

    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, nil, kABPersonSortByLastName);

    CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);

    for (int i = 0; i < nPeople; i++) {
        ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);
        // more thing with `person`
    }

Now I can get all of the contacts in my address book.

It works fine on all of my iDevices!

I'm very sorry about my poor english...

Hopefully, this answer can help you.

Note: Now I don't understand what is source in AddressBook exactly, Can anybody help me?

@Jokinryou Tsui Passing source as nil was the key, thanks! It seems like the source types may correspond to this documentation from Apple : https://developer.apple.com/library/ios/documentation/AddressBook/Reference/ABSourceRef_iPhoneOS/#//apple_ref/doc/constant_group/Source_Types

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!