If you use the ContactsUI you can get close to the behavior that you want. You can enable all of the contacts that have phoneNumbers and disable those that have none. Then your users can search from there:
See the predicateForEnablingContact method on the CNContactPickerViewController.
phoneNumbers.@count > 0
Otherwise you will have to roll your own searchable object, which might give you something like this (note that the enumeration only adds contacts that contain phone numbers).
func findContacts () -> [CNContact]{
let keysToFetch = [CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName),CNContactPhoneNumbersKey] /
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) { (let contact, let stop) -> Void in
/
if contact.phoneNumbers.count > 0 {
contacts.append(contact)
}
}
} catch let e as NSError {
print(e.localizedDescription)
}
return contacts
}
I have not tried this out yet; but you might modify the function above to run on a background thread with a completion handler and assign the output to an array and you are all set.
func findContactsOnBackgroundThread ( completionHandler:(contacts:[CNContact]?)->()) {
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), { () -> Void in
let keysToFetch = [CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName),CNContactPhoneNumbersKey] /
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
/
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)
})
})
}
OR just wrap your call to the first function using:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
self.contacts = self.findContacts()
dispatch_async(dispatch_get_main_queue()) {
//update your UI somehow
//self.tableView!.reloadData()
}
}
Please let me know if this works for by clicking the link below or update the thread if needed.