How to fetch contacts NOT named “John” with Swift

2019-09-24 03:52发布

Is there a way I can fetch contacts using the Contacts framework without an attribute?

Example:

myContactArray = unifiedContactsNotCalled("John")

PS: I know that line is nothing like the real code, it's just a serving suggestion for illustrative purposes

1条回答
霸刀☆藐视天下
2楼-- · 2019-09-24 04:39

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 do-try-catch 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)
    }
}
查看更多
登录 后发表回答