2017-05-25 3 views
3

Je suis aller chercher des contacts de contacts dans le cadre swift3 par le code suivantComment rechercher un contact par adresse email via SearchBar dans 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) 
     } 
    } 
} 

Je suis tous les contacts par ce code, mais mon problème est que je dois rechercher le contact de la barre de recherche par adresse e-mail en utilisant prédicat. Lorsque je cherche par nom, j'obtiens des résultats mais je n'ai aucune idée de comment ajouter un prédicat pour l'adresse email. Je poste la logique de recherche ci-dessous, s'il vous plaît quelqu'un me suggère la bonne façon. Voici ma logique de recherche.

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, 
    ] 
} 

Répondre

1

Vous pouvez faire quelque chose comme ça

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 

}