Dharma
Dharma

Reputation: 81

Unable to filter tableview created using array of dictionary

I am new to swift and Xcode and I have been progressing along with an app that has tableview (of employees with first name space last name) created using a plist dictionary used as NSarray. I am trying to add a search feature.

Here is my code:

var employeeSearch = Array>()

let searchController = UISearchController(searchResultsController: nil)

func getSwiftArrayFromPlist() -> (Array<Dictionary<String,String>>) {

    let path = Bundle.main.path(forResource: "Sheet1", ofType: "plist")
    var arr: NSArray?
    arr = NSArray(contentsOfFile: path!)
    return (arr as? Array<Dictionary<String,String>>)!
}


func searchBarIsEmpty() -> Bool {
    // Returns true if the text is empty or nil
    return searchController.searchBar.text?.isEmpty ?? true
}

// no errors in above function

// I am getting a number of errors in the function below

func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
    employeeSearch = getSwiftArrayFromPlist().filter { $0["lastname".lowercased().contains(searchText.lowercased()]}
    print(employeeSearch)
    searchActive = !employeeSearch.isEmpty
    tblData.reloadData()
}
//getting many errors in above attempt to get a filtered array of dictionary to reload data in tableview 

Any help is appreciated. Thanks.

//Mar 1 - Finally this worked, but only equals condition was going without errors. My expectation was to have contains feature.. func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {

    if searchBar.text == nil || searchBar.text == "" {
        isSearching = false
        view.endEditing(true)
        employee1View.reloadData()
    } else {
        isSearching = true
        employeeSearch = getSwiftArrayFromPlist()

        currentEmployeeSearch = employeeSearch.filter {($0["lastname"]?.lowercased() == searchText.lowercased())}
        //currentEmployeeSearch = employeeSearch.filter {($0["lastname"]?.lowercased().contains(searchText.lowercased())}
        employee1View.reloadData()
    }
}

// *****************************************

Upvotes: 0

Views: 217

Answers (2)

Dharma
Dharma

Reputation: 81

Steve's solution worked. Thank you very much! //********************** func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {

    if searchBar.text == nil || searchBar.text == "" {
        isSearching = false
        view.endEditing(true)
        employee1View.reloadData()
    } else {
        isSearching = true
        employeeSearch = getSwiftArrayFromPlist()

        //currentEmployeeSearch = employeeSearch.filter {($0["lastname"]?.lowercased() == searchText.lowercased())}
        currentEmployeeSearch = employeeSearch.filter {($0["lastname"]?.lowercased().contains(searchText.lowercased())) ?? false}
        employee1View.reloadData()
    }
}

Upvotes: 0

Steve
Steve

Reputation: 951

I think that the filter has incorrect brackets. I believe

employeeSearch = getSwiftArrayFromPlist().filter { $0["lastname".lowercased().contains(searchText.lowercased()]}

should be

employeeSearch = getSwiftArrayFromPlist().filter { $0["lastname"].lowercased().contains(searchText.lowercased())}

Updated answer to help with handling optionals

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    employeeSearch = getSwiftArrayFromPlist()

    guard !searchText.isEmpty else {
        // In here set the array used in the rest of the app equal to employeeSearch
        return employeeSearch
    }

    currentEmployeeSearch = employeeSearch.filter{
        guard let lowerCasedLastName = $0["lastname"].lowercased() else {
            //If we didn't get a lowercased last name from the employeeSearchArray we return false
            // false means we don't want to include that in the search results array
            return false }
        //If we do have a lowerCasedLastName lets see if it contains the search text
        return lowerCasedLastName.contains(searchText.lowercased())
    }

    employee1View.reloadData()

    //Note: Depending on what array the rest of your application uses you will want to set it equal to the value returned from the filter or returned from the else block of the guard against searchText being empty.
}

Upvotes: 0

Related Questions