From 98e512063d343c1153c723f1f35b8963ae15c267 Mon Sep 17 00:00:00 2001 From: Juan Felipe Alvarez Saldarriaga Date: Wed, 22 Apr 2015 20:06:00 -0500 Subject: [PATCH] implements unified people, see #33. unify duplicates records if the contact exists in multiple sources, see http://stackoverflow.com/a/11480352/255463 and #33. --- RHAddressBook/RHAddressBook.h | 3 ++ RHAddressBook/RHAddressBook.m | 72 +++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/RHAddressBook/RHAddressBook.h b/RHAddressBook/RHAddressBook.h index c5e9d59..98ffa46 100644 --- a/RHAddressBook/RHAddressBook.h +++ b/RHAddressBook/RHAddressBook.h @@ -105,6 +105,9 @@ typedef NS_ENUM(NSUInteger, RHAuthorizationStatus) { @property (nonatomic, readonly, copy) NSArray *peopleOrderedByFirstName; @property (nonatomic, readonly, copy) NSArray *peopleOrderedByLastName; +- (NSArray *)peopleUnifiedUsingDefaultSource; +- (NSArray *)peopleUnifiedUsingSource:(RHSource *)source; + -(NSArray*)peopleWithName:(NSString*)name; -(NSArray*)peopleWithEmail:(NSString*)email; -(RHPerson*)personForABRecordRef:(ABRecordRef)personRef; //returns nil if ref not found in the current ab, eg unsaved record from another ab. if the passed recordRef does not belong to the current addressbook, the returned person objects underlying personRef will differ from the passed in value. This is required in-order to maintain thread safety for the underlying AddressBook instance. diff --git a/RHAddressBook/RHAddressBook.m b/RHAddressBook/RHAddressBook.m index 95aaa03..3bd7949 100644 --- a/RHAddressBook/RHAddressBook.m +++ b/RHAddressBook/RHAddressBook.m @@ -645,6 +645,45 @@ -(NSArray*)peopleOrderedByLastName{ return [self peopleOrderedBySortOrdering:kABPersonSortByLastName]; } +/** + * + * + * @return NSArray + */ +- (NSArray *)peopleUnifiedUsingDefaultSource +{ + __block NSArray *result = nil; + + rh_dispatch_sync_for_addressbook(self, ^{ + result = arc_retain([self peopleUnifiedUsingSource:[self defaultSource]]); + }); + + return arc_autorelease(result); +} + +/** + * + * + * @param source + * + * @return NSArray + */ +- (NSArray *)peopleUnifiedUsingSource:(RHSource *)source +{ + __block NSArray *result = nil; + + rh_dispatch_sync_for_addressbook(self, ^{ + CFArrayRef peopleRefs = ABAddressBookCopyArrayOfAllPeopleInSource(_addressBookRef, source.recordRef); + + if (peopleRefs) { + result = arc_retain([self peopleUnifiedForABRecordRefs:peopleRefs]); + CFRelease(peopleRefs); + } + }); + + return arc_autorelease(result); +} + -(NSArray*)peopleWithName:(NSString*)name{ __block NSArray *result = nil; rh_dispatch_sync_for_addressbook(self, ^{ @@ -778,6 +817,39 @@ -(NSArray*)peopleForABRecordRefs:(CFArrayRef)peopleRefs{ return [NSArray arrayWithArray:people]; } +/** + * + * + * @param peopleRefs + * @see http://stackoverflow.com/a/11480352/255463 + * + * @return NSArray + */ +- (NSArray *)peopleUnifiedForABRecordRefs:(CFArrayRef)peopleRefs +{ + if (!peopleRefs) return nil; + + NSMutableSet *people = [NSMutableSet set]; + + rh_dispatch_sync_for_addressbook(self, ^{ + for (CFIndex i = 0; i < CFArrayGetCount(peopleRefs); i++) { + NSMutableSet *contactSet = [NSMutableSet set]; + ABRecordRef personRef = CFArrayGetValueAtIndex(peopleRefs, i); + [contactSet addObject:(__bridge id) personRef]; + + NSArray *linkedRecordsArray = (__bridge NSArray *) ABPersonCopyArrayOfAllLinkedPeople(personRef); + [contactSet addObjectsFromArray:linkedRecordsArray]; + + RHPerson *person = [self personForABRecordRef:personRef]; + if (person) [people addObject:person]; + + CFRelease(personRef); + } + }); + + return people.allObjects; +} + -(RHPerson*)personForABRecordID:(ABRecordID)personID{ __block ABRecordRef recordRef = NULL;