objective-c - 处理由于 iOS 通讯录 API 中的链接卡导致的重复联系人

my upcoming app 的一些 beta 用户报告联系人列表包含大量重复记录。我正在使用 ABAddressBookCopyArrayOfAllPeople 的结果作为我自定义的联系人表格 View 的数据源,令我感到困惑的是,结果与 iPhone 的“联系人”应用程序不同。

当更仔细地查看联系人应用程序时,重复项似乎来自带有“链接卡”的条目。下面的屏幕截图有些模糊,但正如您在最右侧的应用程序中看到的那样,“Celine”出现了两次,而在左侧的“联系人”应用程序中只有一个“Celine”。如果您单击该单个联系人的行,您会得到一张“统一信息”卡片,其中包含两个“链接卡片”(如中间所示,我没有使用 Celine 的联系方式,因为它们不适合一个截图):

关于“链接卡”的问题有 quite一个 few topics在 Apple's forums对于最终用户,但除了许多指向 404 support page 的事实之外,我实际上无法修复所有应用程序用户的通讯录。我更愿意优雅地处理它而不打扰用户。更糟糕的是,我似乎不是唯一一个遇到这个问题的人,因为 WhatsApp is showing the same list containing duplicate contacts .

只是为了清楚重复联系人的来源,我不会存储、缓存或以其他方式尝试对数组 ABAddressBookCopyArrayOfAllPeople 返回的智能。所以重复记录直接来自 API 调用。

有谁知道如何处理或检测这些关联的卡片,以防止出现重复记录? Apple 的通讯录应用可以做到这一点,我们其他人怎么能做到呢?

更新:我编写了一个库并将其放在 Cocoapods 上以解决手头的问题。请参阅下面的答案

最佳答案

一种方法是仅从默认通讯录源中检索联系人:

ABAddressBookRef addressBook = ABAddressBookCreate();
NSArray *people = (__bridge NSArray *)ABAddressBookCopyArrayOfAllPeopleInSource(addressBook, ABAddressBookCopyDefaultSource(addressBook));

但这很蹩脚,对吧?它针对的是设备上的通讯录,而不是 Exchange 或其他花哨的同步通讯录中的额外联系人。

这就是您正在寻找的解决方案:

  1. 遍历 ABRecord 引用
  2. 获取每个相应的“链接引用”(使用 ABPersonCopyArrayOfAllLinkedPeople)
  3. 将它们捆绑在一个 NSSet 中(以便可以唯一标识分组)
  4. 将该 NSSet 添加到另一个 NSSet
  5. 利润?

你现在有一个 NSSet,其中包含链接 ABRecord 对象的 NSSet。总体 NSSet 将与“联系人”应用中的联系人数量相同。

示例代码:

NSMutableSet *unifiedRecordsSet = [NSMutableSet set];

ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef records = ABAddressBookCopyArrayOfAllPeople(addressBook);
for (CFIndex i = 0; i < CFArrayGetCount(records); i++)
{
    NSMutableSet *contactSet = [NSMutableSet set];

    ABRecordRef record = CFArrayGetValueAtIndex(records, i);
    [contactSet addObject:(__bridge id)record];

    NSArray *linkedRecordsArray = (__bridge NSArray *)ABPersonCopyArrayOfAllLinkedPeople(record);
    [contactSet addObjectsFromArray:linkedRecordsArray];

    // Your own custom "unified record" class (or just an NSSet!)
    DAUnifiedRecord *unifiedRecord = [[DAUnifiedRecord alloc] initWithRecords:contactSet];

    [unifiedRecordsSet addObject:unifiedRecord];
    CFRelease(record);
}

CFRelease(records);
CFRelease(addressBook);

_unifiedRecords = [unifiedRecordsSet allObjects];

https://stackoverflow.com/questions/11351454/

相关文章:

iphone - viewWillAppear,viewDidAppear 没有被调用,没有触发

objective-c - 使用 JSON (iOS) 的 Cocoa 错误 3840

iphone - Objective-C 实现文件中方法名后的分号

ios - scaledValueForValue : called on a font that

c++ - UInt8 和 uint8_t 有什么区别

ios - 在从 UIViewController 调用的非保留完成中引用 self 时,weakS

objective-c - 在子类中覆盖初始化

objective-c - 调用 -retainCount 被认为是有害的

objective-c - 如何在 Objective-C 中命名常量?

ios - UIImagePickerController 相机 View 在 iOS 8 上奇怪地