如何从没有filter的设备中检索所有CNContactStore

我试图插入到var contacts: [CNContact] = [] var store = CNContactStore()但我没有find这个工作的正确的代码,我发现这个函数,我需要给这个名字

 func findContactsWithName(name: String) { AppDelegate.sharedDelegate().checkAccessStatus({ (accessGranted) -> Void in if accessGranted { dispatch_async(dispatch_get_main_queue(), { () -> Void in do { let predicate: NSPredicate = CNContact.predicateForContactsMatchingName(name) let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactBirthdayKey, CNContactViewController.descriptorForRequiredKeys()] self.contacts = try self.store.unifiedContactsMatchingPredicate(predicate, keysToFetch:keysToFetch) self.tableView.reloadData() } catch { print("Unable to refetch the selected contact.") } }) } }) } 

我想插入self.contacts所有的logging,而不是只有一个名字相等

更新

基于来自OP的评论,请尝试以下基于CNContactFetchRequest的API来检索所有没有filter的联系人。 我运行在后台线程,以减less任何可能的问题大量的联系人。

 func findContactsOnBackgroundThread ( completionHandler:(contacts:[CNContact]?)->()) { dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { () -> Void in let keysToFetch = [CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName),CNContactPhoneNumbersKey] //CNContactIdentifierKey let fetchRequest = CNContactFetchRequest( keysToFetch: keysToFetch) var contacts = [CNContact]() CNContact.localizedStringForKey(CNLabelPhoneNumberiPhone) fetchRequest.mutableObjects = false fetchRequest.unifyResults = true fetchRequest.sortOrder = .UserDefault let contactStoreID = CNContactStore().defaultContainerIdentifier() print("\(contactStoreID)") do { try CNContactStore().enumerateContactsWithFetchRequest(fetchRequest) { (contact, stop) -> Void in //do something with contact if contact.phoneNumbers.count > 0 { contacts.append(contact) } } } catch let e as NSError { print(e.localizedDescription) } dispatch_async(dispatch_get_main_queue(), { () -> Void in completionHandler(contacts: contacts) }) }) } 

一般来说,当使用CNContactFetchRequest类时,通常将谓词设置为零来检索所有联系人,而不是像您的代码中所描述的那样。

注意

如果你想使用现有的API,那么我build议设置谓词为true:

  NSPredicate(value: true) 

这应该使所有联系人返回。 如果这不起作用,请考虑切换到CNConctactFetchRequest API来枚举联系人。 在这种情况下,您可以设置谓词为零来获取所有联系人(使用CNConctactFetchRequest)。

CNContactFetch谓语

这是如何修改现有的方法:

 func findContacts()->[CNContact] { AppDelegate.sharedDelegate().checkAccessStatus({ (accessGranted) -> Void in if accessGranted { dispatch_async(dispatch_get_main_queue(), { () -> Void in do { let predicate: NSPredicate = NSPredicate(value: true) let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactBirthdayKey, CNContactViewController.descriptorForRequiredKeys()] self.contacts = try self.store.unifiedContactsMatchingPredicate(predicate, keysToFetch:keysToFetch) self.tableView.reloadData() } catch { print("Unable to refetch the selected contact.") } }) } }) } 

并使用:

 let contacts = findContacts() 

苹果有一个更简单的例子:

 let store = CNContactStore() let contacts = try store.unifiedContactsMatchingPredicate(CNContact.predicateForContactsMatchingName("Appleseed"), keysToFetch:[CNContactGivenNameKey, CNContactFamilyNameKey]) 

对于你的用例,你可以尝试像这样修改Apple Sample:

 //Use the reference to look up additional keys constants that you may want to fetch let store = CNContactStore() let contacts = try store.unifiedContactsMatchingPredicate(NSPredicate(value: true), keysToFetch:[CNContactGivenNameKey, CNContactFamilyNameKey]) 

联系人框架的更多Apple示例

修改了Tommie C的XCode 8和Swift 3.0的答案。

 func findContactsOnBackgroundThread ( completionHandler:@escaping (_ contacts:[CNContact]?)->()) { DispatchQueue.global(qos: .userInitiated).async(execute: { () -> Void in let keysToFetch = [CNContactFormatter.descriptorForRequiredKeys(for: .fullName),CNContactPhoneNumbersKey] as [Any] //CNContactIdentifierKey let fetchRequest = CNContactFetchRequest( keysToFetch: keysToFetch as! [CNKeyDescriptor]) var contacts = [CNContact]() CNContact.localizedString(forKey: CNLabelPhoneNumberiPhone) if #available(iOS 10.0, *) { fetchRequest.mutableObjects = false } else { // Fallback on earlier versions } fetchRequest.unifyResults = true fetchRequest.sortOrder = .userDefault let contactStoreID = CNContactStore().defaultContainerIdentifier() print("\(contactStoreID)") do { try CNContactStore().enumerateContacts(with: fetchRequest) { (contact, stop) -> Void in //do something with contact if contact.phoneNumbers.count > 0 { contacts.append(contact) } } } catch let e as NSError { print(e.localizedDescription) } DispatchQueue.main.async(execute: { () -> Void in completionHandler(contacts) }) }) } override func viewDidLoad() { findContactsOnBackgroundThread { (contacts) in self.contactsList = contacts self.tableView.reloadData() } }