与ABAddressBook重复联系

时间:2015-08-19 20:30:38

标签: 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]];

}

1 个答案:

答案 0 :(得分:3)

如果您想避免添加重复项,最简单的方法是构建一组已经添加了某些内容的ABRecordID值,并且只有在该集合中不存在该联系人时才添加该联系人: / p>

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的条目,有一些算法来确定你想要使用哪个名字)。你可以做很多事情。但上面说明了一个简约的解决方案,它将联系人和任何链接的联系人添加到已找到的联系人列表中。