ABAddressBookCopyArrayOfAllPeople和ABAddressBookGetPersonCount返回不同的大小

时间:2011-09-19 16:09:25

标签: iphone ios ios4 iphone-sdk-3.0 abaddressbook

我有一个应用程序偶尔会崩溃,因为ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering()返回的数组与ABAddressBookGetPersonCount()的大小不同。代码的shell如下所示。通常nPeople与数组大小相同。然而,在一个用户的iPhone上(或者至少,如一个用户所报告的那样),nPeople几乎是其两倍。我可以通过使用数组大小​​而不是ABAddressBookGetPersonCount()来停止崩溃。但是,我不确定这是否意味着我没有访问iPhone中的所有联系人。

  • 之前有没有人遇到过这个问题?
  • 为什么数字会有所不同?

我想知道这是否与存储在群组中的联系人有关(我不知道有群组 - 只是一个想法)。此外,从用户的电子邮件地址,我怀疑他们使用MobileMe。我想知道是否与MobileMe同步会创建具有不同recordId的重复项,但不会删除现有的Contact,至少不会像ABAddressBookGetPersonCount()那样。

编辑: 我已经对此进行了一些调查,并对问题的原因有了一个相当好的想法。由于我想要一个排序的联系人数组,我使用了ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering()。这需要一个地址簿源 - 我使用了默认源。我相信可以有各种来源 - 本地来源以及Exchange和MobileMe等其他来源。因此,我的数组最终将只有本地联系人,而ABAddressBookGetPersonCount()返回的数字将包括所有来源 - 因此我的崩溃。因此,我认为最好只使用我的应用程序中的本地数据,并使用ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering而不是ABAddressBookGetPersonCount返回的数组大小。

CFArrayRef allPeople = InSourceWithSortOrdering(addressBook, source, kABPersonSortByLastName);  

    CFIndex nPeople = ABAddressBookGetPersonCount(addressBook);

    for (int i = 0; i < nPeople; i++) 
    {
        ABRecordRef ref = CFArrayGetValueAtIndex(allPeople, i);
    }   

3 个答案:

答案 0 :(得分:13)

ABAddressBookGetPersonCountABAddressBookCopyArrayOfAllPeople提供了不同的数组。

ABAddressBookGetPersonCount - 返回通讯录中的人员记录数。 ABAddressBookCopyArrayOfAllPeople - 返回地址簿中的所有人员记录。

所以有时候同一个人可能会有额外的记录。这就是为什么你可能会有不同的尺寸。

答案 1 :(得分:9)

我今天遇到了这个问题。我的应用程序也崩溃了一些特殊的iDevices。

代码:

    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`
    }

但它有时会崩溃。添加一些断点我发现allPeople的计数小于nPeople

通过Google搜索,我找到了this article。我发现ABAddressBookCopyDefaultSource可能有问题。在这里我得到了默认来源,我必须改为所有来源

代码:

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));
}

然后我得到了

    kABSourceTypeCardDAV
    Count of allPeopleInSource: 7

表示该来源中只有一个来源,只有7个记录。

但在我的地址簿中,我有79个联系人!

然后我犯了一个错误。我将sources传递给ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering,就像这样:

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

allPeople中有多少成员?

72 !!!

完全没有sources的记录数。

我将CFArrayRef传递给ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering作为第二个参数,它需要一个ABRecordRef。如果我通过nil怎么办?

最后,我得到了代码:

    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`
    }

现在,我可以在地址簿中找到所有联系人。

它适用于我的所有iDevices!

我对自己糟糕的英语感到非常抱歉......

希望这个答案可以帮到你。

注意 :现在我不完全理解AddressBook中的source是什么,有人可以帮助我吗?

答案 2 :(得分:3)

@Jokinryou Tsui传递来源为nil是关键,谢谢!似乎源类型可能与Apple的此文档相对应: https://developer.apple.com/library/ios/documentation/AddressBook/Reference/ABSourceRef_iPhoneOS/#//apple_ref/doc/constant_group/Source_Types