Retrieval and maintenance of a large CNContactStore contacts list for a chat application on iOS

285 views Asked by At

I am currently working on a chat application where I need to keep a copy of cncontact store list to match the names and details of the recipients in the app. I am having a hard time when the user is having a very large addressbook. I am running this task on a background thread but it sometimes slows the application and there are times where the recent updates on addressbook is not reflected within the app.

What is the approach when working with a large addressbook list and how should I go ahead with maintaining it? Should I store it all in ManagedContext and recheck it every time the app opens since notifications from Apple when an update happens, does not get reflected in the app at all times? Just wondering how big chats application out there go ahead with having a coup of the list without blocking the UI and it is always up to date. Any help would be much appreciated.

1

There are 1 answers

2
blackjacx On

Do you really need to store a copy of this list in the app. I doubt this should be necessary also for security reasons. I as a user don't have a very good feeling about my contact list is being mirrored to the app.

Don't you need this list only when the user opens the contact list or wants to write a new message? You can use techniques like

  • Pagination for the list view, i.e. load only 20 contacts and load more as the user scrolls
  • Predicates for loading contacts as the user types: CNContact.predicateForContacts(matchingName: "Appleseed")
  • Contact framework has a pretty good API for fetching partial contact data. Some data is much more time intensive than others to fetch. Fetch only what you really need: let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey] as [CNKeyDescriptor]

Fetching contacts with partial data only

let store = CNContactStore()
do {
    let predicate = CNContact.predicateForContacts(matchingName: "Appleseed")
    let contacts = try store.unifiedContacts(matching: predicate, keysToFetch: keysToFetch)
    print("Fetched contacts: \(contacts)")
} catch {
    print("Failed to fetch contact, error: \(error)")
    // Handle the error
}

You can read more about that in the official docs