Reputation: 81
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
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
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