[Solved] How to fetch contacts NOT named “John” with Swift 3 [closed]


Before I outline how to find those that don’t match a name, let’s recap how one finds those that do. In short, you’d use a predicate:

let predicate = CNContact.predicateForContacts(matchingName: searchString)
let matches = try store.unifiedContacts(matching: predicate, keysToFetch: [CNContactFormatter.descriptorForRequiredKeys(for: .fullName)])    // use whatever keys you want

(Obviously, you’d wrap that in a dotrycatch construct, or whatever error handling pattern you want.)

Unfortunately, you cannot use your own custom predicates with the Contacts framework, but rather can only use the CNContact predefined predicates. Thus, if you want to find contacts whose name does not contain “John”, you have to manually enumerateContacts(with:) and build your results from that:

let formatter = CNContactFormatter()
formatter.style = .fullName

let request = CNContactFetchRequest(keysToFetch: [CNContactFormatter.descriptorForRequiredKeys(for: .fullName)])   // include whatever other keys you may need

// find those contacts that do not contain the search string

var matches = [CNContact]()
try store.enumerateContacts(with: request) { contact, stop in
    if !(formatter.string(from: contact)?.localizedCaseInsensitiveContains(searchString) ?? false) {
        matches.append(contact)
    }
}

solved How to fetch contacts NOT named “John” with Swift 3 [closed]