【问题标题】:ABAddressBookCopyArrayOfAllPeople and ABAddressBookGetPersonCount return different sizesABAddressBookCopyArrayOfAllPeople 和 ABAddressBookGetPersonCount 返回不同的大小
【发布时间】:2011-09-19 16:09:25
【问题描述】:

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

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

我想知道这是否与存储在组中的联系人有关(我不知道有组 - 只是一个想法)。另外,从用户的电子邮件地址来看,我怀疑他们使用的是 MobileMe。我想知道与 MobileMe 同步是否会创建具有不同 recordId 的副本,但不会删除现有的联系人,至少不会像 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);
    }   

【问题讨论】:

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


    【解决方案1】:

    ABAddressBookGetPersonCountABAddressBookCopyArrayOfAllPeople 给出不同的数组。

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

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

    【讨论】:

    • 这意味着 ABAddressBookGetPersonCount 应该始终小于 ABAddressBookCopyArrayOfAllPeople?
    • 视情况而定。如果同一个人可能有额外的记录,情况会有所不同。如果每个人都有一个联系电话。那么两者都是一样的。 :) @NikitaP
    【解决方案2】:

    我今天遇到了这个问题。我的应用程序也会在一些特殊的 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

    通过谷歌搜索,我找到了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 上都能正常工作!

    我很抱歉我的英语不好......

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

    注意:现在我不明白地址簿中的source到底是什么,有人可以帮帮我吗?

    【讨论】:

    • 好答案。有时,您通讯录中的所有联系人可能并非来自一个来源。它可能来自 Facebook、不同的 gmail 等。因此,如果您不指定来源,您将获得所有联系人。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-17
      • 2012-03-11
      • 1970-01-01
      • 2013-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-23
      相关资源
      最近更新 更多