To create a list of contacts that merges in linked contacts:
Note: ABPerson references are stored in custom Person class instances. All persons are then stored in a dictionary addressBookDictionary using recordID of each person as the key.
1. Get all ABPersons using ABAddressBookCopyArrayOfAllPeople. Store persons in allPersonRecords array.
2. Iterate through all ABPersons.
2.1 Get a list of linked persons for each ABPerson. Use
ABPersonCopyArrayOfAllLinkedPeople(ABRecordRef person);
If there are no linked contacts, this method will return an array including the person reference him/herself. So if the return array has a count > 1, the person has linked contacts.
2.2 Add the linked persons to a NSMutableSet. These linked persons will be skipped and not processed in future iterations.
2.3 Create a Person instance for the current ABPerson.
2.4 Merge linked person information into Person instance. A linked person may have different phone numbers, so you need to merge them together.
NSArray *allPersonRecords = (NSArray *) ABAddressBookCopyArrayOfAllPeople(self.addressBook);
NSMutableSet *linkedPersonsToSkip = [[NSMutableSet alloc] init];
for (int i=0; i<[allPersonRecords count]; i++){
ABRecordRef personRecordRef = [allPersonRecords objectAtIndex:i];
// skip if contact has already been merged
//
if ([linkedPersonsToSkip containsObject:personRecordRef]) {
continue;
}
// Create object representing this person
//
Person *thisPerson = [[Person alloc] initWithPersonRef:personRecordRef];
// check if there are linked contacts & merge their contact information
//
NSArray *linked = (NSArray *) ABPersonCopyArrayOfAllLinkedPeople(personRecordRef);
if ([linked count] > 1) {
[linkedPersonsToSkip addObjectsFromArray:linked];
// merge linked contact info
for (int m = 0; m < [linked count]; m++) {
ABRecordRef iLinkedPerson = [linked objectAtIndex:m];
// don't merge the same contact
if (iLinkedPerson == personRecordRef) {
continue;
}
[thisPerson mergeInfoFromPersonRef:iLinkedPerson];
}
}
[self.addressBookDictionary setObject:thisPerson forKey:thisPerson.recordID];
[thisPerson release];
[linked release];
}
[linkedPersonsToSkip release];
[allPersonRecords release];