traiantomescu
traiantomescu

Reputation: 65

Swift 4.2 Search contacts with Search Bar using Contacts Framework

I'm currently working on a Contact app just to test some features and I'm stuck with the search bar. I can't search between all my contacts in the homepage. Swift 4.2 and Xcode 10

class ContactsViewController: UITableViewController, CNContactViewControllerDelegate, UISearchBarDelegate {
// Outlet for Search Bar
@IBOutlet weak var searchBar: UISearchBar!

this is the definition of my Delegate on IBOutlet

then my func to show contacts in the homepage

/ * Show Contacts *
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if contactList != nil {
        return contactList.count
    }
    return 0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "contactCell", for: indexPath)

    let contact: CNContact!
    contact = contactList[indexPath.row]

    cell.textLabel?.text = "\(contact.givenName) \(contact.familyName)"
    return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let contact = contactList[indexPath.row]
    let controller = CNContactViewController(for: contact)
    navigationController?.pushViewController(controller, animated: true)
}

How can I do this searchBar look through my contacts using as key Name or Surname.

Here is one of my attempt but I get an error with contains:

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    if searchBar.text == nil || searchBar.text == "" {
        inSearchMode = false

        view.endEditing(true)

        tableView.reloadData()
    } else {
        inSearchMode = true

        filteredData = contactList.filter({$0.contains(searchBar.text!)})

        tableView.reloadData()
    }
}

Upvotes: 3

Views: 3351

Answers (1)

rmaddy
rmaddy

Reputation: 318934

Your contactList array contains CNContact instances. So the $0 in your filter is a CNContact. contains fails because CNContact has no contains method.

Think about what you would need to write if you had a single CNContact variable and you want to see if the contact's name contained the search text.

And you probably don't want contains because you probably want to do a case-insensitive, diacritic-insentsitve search.

Here's an example by looking at the contact's given and family name properties. Add other properties as needed:

filteredData = contactList.filter {
    $0.givenName.range(of: searchBar.text!, options: [.caseInsensitive, .diacriticInsensitive ]) != nil ||
    $0.familyName.range(of: searchBar.text!, options: [.caseInsensitive, .diacriticInsensitive ]) != nil
}

Upvotes: 8

Related Questions