CNContactStore number of contact entries

I need to get the number of all contacts on a user device. A resignation message in ABAddressBookGetPersonCount says:

use the number of fetch results for CNContactFetchRequest with predicate = nil

Here is what I did after this tutorial:

__block NSUInteger contactsCount = 0; NSError *error; CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:@[CNContactGivenNameKey]]; BOOL success = [self.contactStore enumerateContactsWithFetchRequest:request error:&error usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) { contactsCount += 1; }]; if (!success || error) { NSLog(@"error counting all contacts, error - %@", error.localizedDescription); } 

However, it looks horrible in terms of performance. I have not found another way to get an account without listing the CNContact objects. Did I miss something?

Thank you in advance!

+5
source share
2 answers

This is old, but in case someone else stumbles upon it, this can be done by listing with 0 keys to extract instead of 1.

 __block NSUInteger contactsCount = 0; NSError *error; CNContactFetchRequest *request = [[CNContactFetchRequest alloc] initWithKeysToFetch:@[]]; BOOL success = [self.contactStore enumerateContactsWithFetchRequest:request error:&error usingBlock:^(CNContact * _Nonnull contact, BOOL * _Nonnull stop) { contactsCount += 1; }]; if (!success || error) { NSLog(@"error counting all contacts, error - %@", error.localizedDescription); } 

Using 0 keys, I was able to start counting on the device with 10,000 contacts in 0.8 seconds (whereas for 1 second it took 14 seconds).

+2
source

Swift 3 version packaged as a function of the class.

 class func contactCount() -> Int? { let contactStore = CNContactStore() var contactsCount: Int = 0 let contactFetchRequest = CNContactFetchRequest(keysToFetch: []) do { try contactStore.enumerateContacts(with: contactFetchRequest) { (contact, error) in contactsCount += 1 } } catch { print("Error counting all contacts.\nError: \(error)") return nil } return contactsCount } 

It’s often better to use contact storage than to create another one:

 class func contactCount(store: CNContactStore?) -> Int? { let contactStore: CNContactStore if let suppliedStore = store { contactStore = suppliedStore } else { contactStore = CNContactStore() } var contactsCount: Int = 0 let contactFetchRequest = CNContactFetchRequest(keysToFetch: []) do { try contactStore.enumerateContacts(with: contactFetchRequest) { (contact, error) in contactsCount += 1 } } catch { print("Error counting all contacts.\nError: \(error)") return nil } return contactsCount } 
0
source

Source: https://habr.com/ru/post/1247365/


All Articles