How to Use Querystartingatvalue in My Searchcontroller to Search for Users

How can I use queryStartingAtValue in my searchcontroller to search for users?

The code in the question is almost correct, just need to tweak it to ensure the enumeration var is a snapshot and then use it with Mapper.

As a user enters a user name, recursively call this with each keypress; so if they are typing in Leroy, L is typed first and this code will retrieve all nodes where the username value starts with "L". Then the user types 'e' making it 'Le' etc etc.

func searchUsers(text: String) {
if text.count > 0 {
self.usersArray = [] //clear the array each time
let endingText = text + "\u{f8ff}"
databaseRef.child("profile").queryOrdered(byChild: "username")
.queryStarting(atValue: text)
.queryEnding(atValue: endingText)
.observeSingleEvent(of: .value, with: { snapshot in

for child in snapshot.children {
let childSnap = child as! DataSnapshot
let userObj = Mapper<UserModel>().map(JSONObject: childSnap.value!)
userObj?.uid = childSnap.key
if childSnap.key != self.loggedInUser?.uid { //ignore this user
self.usersArray.append(userObj!)
}
}
self.tableView.reloadData()
})
}
} //may need an else statement here to clear the array when there is no text

EDIT:

OP requested code for handling the search through a searchBar and a if statement to prevent searching if there are is no text. Here's the delegate method for that which calls the searchUsers function above

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

self.searchUsers(text: searchText)
}

EDIT:

OP wanted to see my viewDidLoad function, as unexciting as it is, so here it is.

class ViewController: UIViewController, UISearchBarDelegate 
override func viewDidLoad() {
super.viewDidLoad()

// Do any additional setup after loading the view.
}

Why dosent my tableview show search results?

You have 2 arrays usersArray and filteredUsers

if childSnap.key != self.loggedInUser?.uid { //ignore this user
self.usersArray.append(userObj!)
}
...
self.tableView.reloadData()

so the the above reload has no effect as you always use

let user = filteredUsers[indexPath.row]

in cellForRowAt , in such cases you should have a var like

var isSearching = false

and alter it when you search then in all delegate & dataSource methods

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return isSearching ? filteredUsers.count : usersArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! FollowTableViewCell

let user = isSearching ? filteredUsers[indexPath.row] : usersArray[indexPath.row]
.....
}

func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
isSearching = true
}

func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
isSearching = false
}

func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
isSearching = false
}

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
isSearching = false
}

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

filteredUsers = usersArray.filter { /* do filter */ }

if(filteredUsers.count == 0){
isSearching = false
} else {
isSearching = true
}
self.tableView.reloadData()
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "user", sender: isSearching ? self.filteredUsers[indexPath.row] : self.usersArray[indexPath.row])
}


Related Topics



Leave a reply



Submit