iOS联系人如何通过电话号码获取联系人

我只想通过电话号码联系给定的姓名和姓氏。 我试过这个,但是这太慢了,CPU达到了120%以上。

let contactStore = CNContactStore() let keys = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactPhoneNumbersKey] var contacts = [CNContact]() do { try contactStore.enumerateContactsWithFetchRequest(CNContactFetchRequest.init(keysToFetch: keys), usingBlock: { (contact, cursor) in if (!contact.phoneNumbers.isEmpty) { for phoneNumber in contact.phoneNumbers { if let phoneNumberStruct = phoneNumber.value as? CNPhoneNumber { do { let libPhone = try util.parseWithPhoneCarrierRegion(phoneNumberStruct.stringValue) let phoneToCompare = try util.getNationalSignificantNumber(libPhone) if formattedPhone == phoneToCompare { contacts.append(contact) } }catch { print(error) } } } } }) if contacts.count > 0 { contactName = (contacts.first?.givenName)! + " " + (contacts.first?.familyName)! print(contactName) completionHandler(contactName) } }catch { print(error) } 

另外,当我使用phonenumber工具包查找联系其增加的cpu和迟到的反应。

 var result: [CNContact] = [] let nationalNumber = PhoneNumberKit().parseMultiple([phoneNumber]) let number = nationalNumber.first?.toNational() print(number) for contact in self.addressContacts { if (!contact.phoneNumbers.isEmpty) { let phoneNumberToCompareAgainst = number!.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("") for phoneNumber in contact.phoneNumbers { if let phoneNumberStruct = phoneNumber.value as? CNPhoneNumber { let phoneNumberString = phoneNumberStruct.stringValue let nationalContactNumber = PhoneNumberKit().parseMultiple([phoneNumberString]) let nationalContactNumberString = nationalContactNumber.first?.toNational() if nationalContactNumberString == number { result.append(contact) } } } } } return result 

你的实现的问题是,你在每一个你正在做的search中访问地址簿。

相反,如果你在第一次访问后将内存中的地址簿内容,你不会达到这么高的CPU使用率。

  1. 首先在控制器中保存一个懒惰的variables,它将保存地址簿的内容:

     lazy var contacts: [CNContact] = { let contactStore = CNContactStore() let keysToFetch = [ CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName), CNContactEmailAddressesKey, CNContactPhoneNumbersKey, CNContactImageDataAvailableKey, CNContactThumbnailImageDataKey] // Get all the containers var allContainers: [CNContainer] = [] do { allContainers = try contactStore.containersMatchingPredicate(nil) } catch { print("Error fetching containers") } var results: [CNContact] = [] // Iterate all containers and append their contacts to our results array for container in allContainers { let fetchPredicate = CNContact.predicateForContactsInContainerWithIdentifier(container.identifier) do { let containerResults = try contactStore.unifiedContactsMatchingPredicate(fetchPredicate, keysToFetch: keysToFetch) results.appendContentsOf(containerResults) } catch { print("Error fetching results for container") } } return results }() 
    1. 当您正在查找与特定电话号码的联系人时,请遍历内存数组:

      func searchForContactUsingPhoneNumber(phoneNumber: String) -> [CNContact] { var result: [CNContact] = [] for contact in self.contacts { if (!contact.phoneNumbers.isEmpty) { let phoneNumberToCompareAgainst = phoneNumber.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("") for phoneNumber in contact.phoneNumbers { if let phoneNumberStruct = phoneNumber.value as? CNPhoneNumber { let phoneNumberString = phoneNumberStruct.stringValue let phoneNumberToCompare = phoneNumberString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("") if phoneNumberToCompare == phoneNumberToCompareAgainst { result.append(contact) } } } } } return result } 

我testing了一个非常大的地址簿,它工作顺利。

这里是整个视图控制器修补在一起作为参考。

 import UIKit import Contacts class ViewController: UIViewController { lazy var contacts: [CNContact] = { let contactStore = CNContactStore() let keysToFetch = [ CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName), CNContactEmailAddressesKey, CNContactPhoneNumbersKey, CNContactImageDataAvailableKey, CNContactThumbnailImageDataKey] // Get all the containers var allContainers: [CNContainer] = [] do { allContainers = try contactStore.containersMatchingPredicate(nil) } catch { print("Error fetching containers") } var results: [CNContact] = [] // Iterate all containers and append their contacts to our results array for container in allContainers { let fetchPredicate = CNContact.predicateForContactsInContainerWithIdentifier(container.identifier) do { let containerResults = try contactStore.unifiedContactsMatchingPredicate(fetchPredicate, keysToFetch: keysToFetch) results.appendContentsOf(containerResults) } catch { print("Error fetching results for container") } } return results }() override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let contact = searchForContactUsingPhoneNumber("(555)564-8583") print(contact) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } func searchForContactUsingPhoneNumber(phoneNumber: String) -> [CNContact] { var result: [CNContact] = [] for contact in self.contacts { if (!contact.phoneNumbers.isEmpty) { let phoneNumberToCompareAgainst = phoneNumber.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("") for phoneNumber in contact.phoneNumbers { if let phoneNumberStruct = phoneNumber.value as? CNPhoneNumber { let phoneNumberString = phoneNumberStruct.stringValue let phoneNumberToCompare = phoneNumberString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet).joinWithSeparator("") if phoneNumberToCompare == phoneNumberToCompareAgainst { result.append(contact) } } } } } return result } } 

我用flohei的答案为懒惰的variables部分。