I want to build a ContactsTableViewController
like that of GroupMe. It shows all my Address Book contacts and even which ones are GroupMe users.
It seems that ABPeoplePickerNavigationController cannot be customized.
So, if I access Address Book contacts with ABAddressBook
& ABPerson
, what's the best way to display them with a custom UITableViewController
?
I don't want to just load all Address Book contacts into an NSArray
because that could kill the memory (I know people who have thousands of Address Book contacts on their phones.). I'm used to using Core Data & NSFetchedResultsController
for large result sets like this. But, to do that, I'd have to create an ABPerson
model in Core Data, which would be easy, but keeping it in sync with the Address Book seems challenging and sort of silly.
What's the best way to relate/link GroupMe contacts to Address Book contacts?
Is there anything else I should know/consider when trying to recreate this GroupMe-style interface?
I'm one of the GroupMe iOS developers and this is what we do.
We scan the users address book and store it in Core Data. We have a Contact object that has a 1-to-many against phone numbers, and a 1-to-many against email addresses. The first scan can take a little time if there a lot of contacts, but in each subsequent scan we ignore any ABRecordRef
that has a kABPersonModificationDateProperty
before our last scan. This makes updates a lot faster.
Then, assuming the user has opted into syncing contacts, we upload phone numbers and email addresses to our server which will match against existing GroupMe users.
Finally, we pull GroupMe relationships based on matches (from phone, email, facebook, twitter) and store those in Core Data as well. If relationship was made because of a phone/email already existing in the user's address book, we pass those values back in the relationships so we can create a 1-to-1 relationship between the GroupMe relationship and the contact we stored in Core Data in step 1. This way we can easily create NSFetchRequest
s for local contacts, or GroupMe relationships and have their relationship details available at any point (so we can show that a local contact is a GroupMe user etc -- like Aaron G. in your screenshot)
We use a NSFetchedResultsController
, as well, so we can get updates reflected in the UI if our background operations find any new contacts/relationships..
The only other tips are to make sure you have your fetch request prefetch all relationships so loading relationship reasons don't hit core data as you scroll to populate faults.
And yeah, while keeping your Core Data n'sync with the user's address book is more tedious than silly, it's worth it so you can have easy access to it and for queries that need to know all that jazz.