我通过以下代码
从swift3中的联系人框架中获取联系人 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)
}
}
}
我通过此代码获得了所有联系人但我的问题是我必须使用谓词通过电子邮件地址搜索搜索栏中的联系人。当我按名称搜索时,我得到的结果,但我不知道如何为电子邮件地址添加谓词。我在下面发布搜索逻辑,请任何人建议我正确的方式。这是我的搜索逻辑。
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,
]
}
答案 0 :(得分:1)
你可以做这样的事情
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
}
答案 1 :(得分:0)
有更好的方法:)
let predicate = CNContact.predicateForContacts(matchingEmailAddress: "some@example.com")