【问题标题】:CNContactStore count of contact recordsCNContactStore 联系人记录计数
【发布时间】:2016-04-18 13:34:53
【问题描述】:

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

对 CNContactFetchRequest 使用 predicate = nil 的获取结果计数

这是我按照该指南编写的内容:

 __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 对象的情况下,我还没有找到另一种获取计数的方法。我错过了什么吗?

提前谢谢你!

【问题讨论】:

  • 您的代码与弃用消息中的建议有何相似之处?
  • 还有其他方法可以执行 CNContactFetchRequest 吗?

标签: ios cncontact cncontactstore


【解决方案1】:

这是旧的,但如果其他人偶然发现它,可以通过使用 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 秒)。

【讨论】:

  • 这其实是一个非常好的观点!我仍然希望苹果增加一个合法的方式来计算这个数量。 Ingurss 一个简单的缓存属性将是唯一正确的方法。再次感谢您的洞察力。
【解决方案2】:

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
} 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多