2016-04-18 10 views
5

Potrzebuję uzyskać liczbę wszystkich kontaktów na urządzeniu użytkownika. Komunikat deprecation na ABAddressBookGetPersonCount mówi: IlośćCNContactStore liczba rekordów kontaktów

wykorzystanie sprowadzić wyniki dla CNContactFetchRequest z orzecznika = nil

Oto co wymyśliłem po tych wskazówek:

__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); 
} 

Jednak to wygląda okropne pod względem wydajności. Nie znalazłem innego sposobu na uzyskanie liczby bez wyliczenia obiektów CNContact. Czy czegoś brakuje?

Z góry dziękuję!

+0

jaki jest kod coś jak sugestia w komunikacie amortyzacyjne? – trojanfoe

+0

Czy istnieje inny sposób na wykonanie CNContactFetchRequest? –

Odpowiedz

2

To jest stary, ale w przypadku ktokolwiek inny natyka się na niej, może to być osiągnięte poprzez działanie wyliczenie z 0 klawiszy sprowadzić zamiast 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); 
} 

z 0 klawiszami, udało mi się uruchomić licznik na urządzeniu z 10 000 kontaktów w ciągu 0,8 sekundy (podczas gdy zajęło to 14 sekund za pomocą 1 klucza).

+0

To naprawdę bardzo dobry punkt! Nadal chciałbym, aby Apple dodał legalny sposób na liczenie. Prawdopodobnie jedyna właściwa droga do zrobienia to prosta własność buforowana. Jeszcze raz dziękuję za wgląd. –

0

Wersja Swift 3, zapakowana jako funkcja klasy.

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 
} 

Często lepiej byłoby ponowne sklep kontaktów niż stworzyć jeszcze jeden:

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 
} 
Powiązane problemy