ios - 与ABAddressBook重复联系

标签 ios objective-c nsarray abaddressbook nsset

我正在使用ABAddressBook,可以显示每个联系人,但是我有一些重复的联系人。

我已经阅读了这个主题:Dealing with duplicate contacts due to linked cards in iOS' Address Book API,但是无法解决问题。

我想在我的代码中使用此代码,但我没有成功..:

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];

这是我的代码:
- (void)getPersonOutOfAddressBook
{
    //1
    CFErrorRef error = NULL;
    ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);

    if (addressBook != nil) {
        NSLog(@"Succesful.");

        //2
        NSArray *allContacts = (__bridge_transfer NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBook);


        //3
        NSUInteger i = 0; for (i = 0; i < [allContacts count]; i++)
        {
            Person *person = [[Person alloc] init];
            ABRecordRef contactPerson = (__bridge ABRecordRef)allContacts[i];

            //4
            NSString *firstName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson,
                                                                                  kABPersonFirstNameProperty);
            if (firstName == nil)
            {
                firstName = @"";
            }
            NSString *lastName = (__bridge_transfer NSString *)ABRecordCopyValue(contactPerson, kABPersonLastNameProperty);
            if (lastName == nil)
            {
                lastName = @"";
            }
            NSString *fullName = [NSString stringWithFormat:@"%@ %@", firstName, lastName];

            person.firstName = firstName; person.lastName = lastName;
            person.fullName = fullName;



            //phone
            //5
            ABMultiValueRef phones = ABRecordCopyValue(contactPerson, kABPersonPhoneProperty);

            //6
            NSUInteger j = 0;
            for (j = 0; j < ABMultiValueGetCount(phones); j++) {
                NSString *phone = (__bridge_transfer NSString *)ABMultiValueCopyValueAtIndex(phones, j);

                if (j == 0) {
                    person.mainNumber = phone;
                }
                else if (j==1) person.secondNumber = phone;
            }

            //7
            [person.mainNumber stringByReplacingOccurrencesOfString:@" " withString:@""];
            [person.mainNumber stringByReplacingOccurrencesOfString:@"(" withString:@""];
            [person.mainNumber stringByReplacingOccurrencesOfString:@")" withString:@""];
            [person.mainNumber stringByReplacingOccurrencesOfString:@"+336" withString:@"06"];
            [self.tableData addObject:person];
            [self.contact addObject:person.fullName];

        }

        //8
        CFRelease(addressBook);
    } else {
        //9
        NSLog(@"Error reading Address Book");
    }
    NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:@"fullName" ascending:YES];
    [self.tableData sortUsingDescriptors:[NSArray arrayWithObject:sorter]];

}

最佳答案

如果要避免添加重复项,可能最简单的方法是构建一组已经添加了某些内容的ABRecordID值,并且仅在该组中不存在联系人的情况下才添加该联系人:

self.tableData = [NSMutableArray array];
NSMutableSet *foundIDs = [NSMutableSet set];

NSArray *allContacts = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook));

for (id record in allContacts) {
    ABRecordRef contactPerson = (__bridge ABRecordRef)record;
    ABRecordID recordId = ABRecordGetRecordID(contactPerson);
    if (![foundIDs containsObject:@(recordId)]) {
        Person *person = [[Person alloc] init];

        // get name

        person.firstName = CFBridgingRelease(ABRecordCopyValue(contactPerson, kABPersonFirstNameProperty)) ?: @"";
        person.lastName = CFBridgingRelease(ABRecordCopyValue(contactPerson, kABPersonLastNameProperty)) ?: @"";
        person.fullName = [NSString stringWithFormat:@"%@ %@", person.firstName, person.lastName];

        // get phones

        ABMultiValueRef phones = ABRecordCopyValue(contactPerson, kABPersonPhoneProperty);
        for (NSUInteger j = 0; j < ABMultiValueGetCount(phones); j++) {
            // I presume you meant to use mutable string and `replaceOccurrencesOfString`:

            NSMutableString *phone = [CFBridgingRelease(ABMultiValueCopyValueAtIndex(phones, j)) mutableCopy];

            [phone replaceOccurrencesOfString:@" "    withString:@""   options:0 range:NSMakeRange(0, phone.length)];
            [phone replaceOccurrencesOfString:@"("    withString:@""   options:0 range:NSMakeRange(0, phone.length)];
            [phone replaceOccurrencesOfString:@")"    withString:@""   options:0 range:NSMakeRange(0, phone.length)];
            [phone replaceOccurrencesOfString:@"+336" withString:@"06" options:0 range:NSMakeRange(0, phone.length)];

            if (j == 0)     person.mainNumber   = phone;
            else if (j==1)  person.secondNumber = phone;
        }
        CFRelease(phones);

        // add the `Person` record

        [self.tableData addObject:person];

        // add the ID for this person (and all linked contacts) to our set of `foundIDs`

        NSArray *linkedPeople = CFBridgingRelease(ABPersonCopyArrayOfAllLinkedPeople(contactPerson));
        if (linkedPeople) {
            for (id record in linkedPeople) {
                [foundIDs addObject:@(ABRecordGetRecordID((__bridge ABRecordRef)record))];
            }
        } else {
            [foundIDs addObject:@(recordId)];
        }
    }
}

CFRelease(addressBook);

NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"fullName" ascending:YES];
[self.tableData sortUsingDescriptors:@[descriptor]];

话虽如此,您可能还应该遍历所有链接的联系人并在其中查找电话号码。也许也可以对名称进行一些验证(例如,如果您有一个J. D. Salinger条目,而另一个有John David Salinger条目,则有一些算法可以弄清楚您要使用哪个名称)。您可以做很多事情。但是以上内容说明了一种简约的解决方案,该解决方案将联系人和任何链接的联系人添加到已找到的联系人列表中。

关于ios - 与ABAddressBook重复联系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32105106/

相关文章:

objective-c - iOS:从 Storyboard 中唯一标识 ViewControllers

ios - 使用 HTTPCookieStorage.shared 在 URLSessionConfiguration.background 中授权失败(cookes 未发送)

objective-c - 将 libccv 与 UIImage 一起使用

ios - 由于空数组导致应用程序崩溃

ios - 如何设置可访问性容器以使手势正常工作?

ios - 使用 XCPShowView 时为 "Playground execution failed"(标识符 : view:)

objective-c - 在 plist 文件中存储 Objective-C 代码

ios - 如何在 objective-c 中的按钮 Segue 后导航回来

iphone - float* array 到 NSArray, iOS

iphone - 如何从不同的 .m 文件中的数组中获取项目?