如何通过搜索栏在swift 3中通过电子邮件地址搜索联系人?

问题描述:

我对下面的代码如何通过搜索栏在swift 3中通过电子邮件地址搜索联系人?

func getContctFromContactBook(_ completion: @escaping ContactsHandler) { 

    if contactsStore == nil { 
     //ContactStore is control for accessing the Contacts 
     contactsStore = CNContactStore() 
    } 

    switch CNContactStore.authorizationStatus(for: CNEntityType.contacts) { 
    case CNAuthorizationStatus.denied, CNAuthorizationStatus.restricted: 
     //User has denied the current app to access the contacts. 

     let productName = Bundle.main.infoDictionary!["CFBundleName"]! 

     let alert = UIAlertController(title: "Unable to access contacts", message: "\(productName) does not have access to contacts. Kindly enable it in privacy settings ", preferredStyle: UIAlertControllerStyle.alert) 
     let okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: { action in 
     }) 
     alert.addAction(okAction) 

    case CNAuthorizationStatus.notDetermined: 
     //This case means the user is prompted for the first time for allowing contacts 
     contactsStore?.requestAccess(for: CNEntityType.contacts, completionHandler: { (granted, error) -> Void in 
      //At this point an alert is provided to the user to provide access to contacts. This will get invoked if a user responds to the alert 
      if (!granted){ 
       DispatchQueue.main.async(execute: {() -> Void in 
       }) 
      } 
      else{ 
      } 
     }) 
    case CNAuthorizationStatus.authorized: 
     //Authorization granted by user for this app. 
     var contactsArray = [CNContact]() 

     let contactFetchRequest = CNContactFetchRequest(keysToFetch: keysToFetch as [CNKeyDescriptor]) 

     do { 
      try contactsStore?.enumerateContacts(with: contactFetchRequest, usingBlock: { (contact, stop) -> Void in 
       //Ordering contacts based on alphabets in firstname 
       contactsArray.append(contact) 
      }) 
      completion(contactsArray, nil) 
     } 
     catch let error as NSError { 
      print(error.localizedDescription) 
     } 
    } 
} 

获取从swift3接触框架的接触我得到这个代码的所有联系人,但我的问题是,我使用谓词来搜索电子邮件地址从搜索栏接触。当我按名称搜索时,我正在获取结果,但我不知道如何为电子邮件地址添加谓词。我在下面发布搜索逻辑,请任何一个建议我正确的方式。这是我的搜索逻辑。

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { 
if (searchText.characters.count > 0) 
{ 
    let predicate: NSPredicate 
    if searchText.characters.count > 0 { 
     predicate = CNContact.predicateForContacts(matchingName: searchText) 

    } else { 
     predicate = CNContact.predicateForContactsInContainer(withIdentifier: contactsStore!.defaultContainerIdentifier()) 
    } 
    let store = CNContactStore() 
    do { 

     filteredContacts = try store.unifiedContacts(matching: predicate, 
                keysToFetch: allowedContactKeys()) 
    } 
    catch { 
     print("Error!") 
    } 
} 
else 
{ 
    self.filteredContacts = self.contactsArray 
} 

self.tblContact.reloadData() 
} 

    func allowedContactKeys() -> [CNKeyDescriptor]{ 
     //We have to provide only the keys which we have to access. We should avoid unnecessary keys when fetching the contact. Reducing the keys means faster the access. 

    return [CNContactEmailAddressesKey as CNKeyDescriptor, 
      CNContactNamePrefixKey as CNKeyDescriptor, 
      CNContactGivenNameKey as CNKeyDescriptor, 
      CNContactFamilyNameKey as CNKeyDescriptor, 
      CNContactOrganizationNameKey as CNKeyDescriptor, 
      CNContactBirthdayKey as CNKeyDescriptor, 
      CNContactImageDataKey as CNKeyDescriptor, 
      CNContactThumbnailImageDataKey as CNKeyDescriptor, 
      CNContactImageDataAvailableKey as CNKeyDescriptor, 
      CNContactPhoneNumbersKey as CNKeyDescriptor, 
    ] 
} 

你可以做这样的事情

func searchContact(searchString: String) -> [CNContact] { 

     //Fetch 
     let contactStore: CNContactStore = CNContactStore() 
     var contacts: [CNContact] = [CNContact]() 
     let fetchRequest: CNContactFetchRequest = CNContactFetchRequest(keysToFetch: [CNContactVCardSerialization.descriptorForRequiredKeys()]) 

     do { 
      try contactStore.enumerateContacts(with: fetchRequest, usingBlock: { 
       contact, _ in 
       contacts.append(contact) }) 

     } catch { 
      print("Get contacts \(error)") 
     } 

     //Search 
     var resultArray: [CNContact] = [CNContact]() 

     for item in contacts { 

      for email in item.emailAddresses { 
       if email.value.contains(searchString) { 
        resultArray.append(item) 
       } 
      } 
     } 

     let withoutDuplicates: [CNContact] = [CNContact](Set(resultArray)) 
     return withoutDuplicates 

}