CNContactStore联系人记录的计数

时间:2016-04-18 13:34:53

标签: ios cncontact cncontactstore

我需要获取用户设备上所有联系人的号码。 ABAddressBookGetPersonCount上的弃用消息说:

  

使用带有谓词= nil

的CNContactFetchRequest的获取结果计数

以下是我在该指导下编写的内容:

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

然而,就性能而言,这看起来很糟糕。我还没有找到另一种获取计数而不枚举CNContact对象的方法。我错过了什么吗?

提前谢谢!

2 个答案:

答案 0 :(得分:2)

这是旧的,但万一其他人偶然发现它,可以通过使用0键进行枚举而不是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);
}

使用0键,我能够在0.8秒内在具有10,000个联系人的设备上运行计数(而使用1个键则需要14秒)。

答案 1 :(得分:1)

Swift 3版本,打包为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
}

重复使用联系人商店通常比创建另一个商店更好:

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
}