How to access iOS Contacts in batches?

I'm trying to implement a contacts reader in Xamarin.iOS which tries to iterate over the iOS contacts in all CNContactStore containers. Instead of loading all contacts into memory, I need to iterate over a contacts resultset batch by batch (paging contacts). However all the examples that I saw in SO load almost all contacts into memory first.

The link below has loads of similar examples that read all contacts at once. Although these examples have logic which iterates one by one, it is not evident to me how to skip N and take the next N number of contacts without iterating from the beginning on the next call (which looks sub optimal at least to me).

stackoverflow.com/questions/32669612/how-to-fetch-all-contacts-record-in-ios-9-using-contacts-framework

Apple's own documentation reads:

developer.apple.com/documentation/contacts/cncontactstore#//apple_ref/occ/instm/CNContactStore/enumerateContactsWithFetchRequest:error:usingBlock:

When fetching all contacts and caching the results, first fetch all contacts identifiers, then fetch batches of detailed contacts by identifiers as required

I was able to do this easily for Android using the cursor based approach available in its SDK. Is this at all possible for iOS? If not how can we handle a large number of contacts (e.g. something above 2000, etc.).

Thanks in advance.

Answers

  • LandLuLandLu Member, Xamarin Team Xamurai

    If Apple offers the fetch all contacts method, I don't think this will be a trouble to handle large contacts in the memory.
    You can also add some predicates to retrieve special contacts like:

    var predicate = CNContact.GetPredicateForContacts("a");
    
    NSString[] propertiesArray = { CNContactKey.FamilyName, CNContactKey.GivenName, CNContactKey.PhoneNumbers};    
    CNContactStore store = new CNContactStore();
    
    NSError fetchError;
    CNContact[] contacts = store.GetUnifiedContacts(predicate, propertiesArray, out fetchError);
    

    This will only return the contacts containing the character a in the full name.
    EnumerateContacts() may be another choice:

    store.EnumerateContacts(request, out fetchError, delegate(CNContact contact, ref bool stop)
    {
    
    });
    

    When we set the stop to true, this lambda will stop fetch contact.

Sign In or Register to comment.