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

后端 未结 2 1972
有刺的猬
有刺的猬 2021-01-28 20:56

I have previously asked a question about searching for users the most cost-efficient way (without having to load up every user in the entire database.

My code before the

相关标签:
2条回答
  • 2021-01-28 21:34

    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.
        }
    
    0 讨论(0)
  • 2021-01-28 21:47

    I am adding this as a separate answer as the OP has additional indirectly related questions:

    This is my entire codebase

    class ViewController: UIViewController, UISearchBarDelegate {
        @IBOutlet var searchBarOutlet: [UISearchBar]!
         override func viewDidLoad() {
            super.viewDidLoad()
    
            // Do any additional setup after loading the view, typically from a nib.
            self.searchBar.delegate = self
         }
    
        var userNamesArray = [String]()
        func searchBar(_ searchBar: UISearchBar,
                       textDidChange searchText: String) {
    
            self.searchUsers(text: searchText)
        }
    
        func searchUsers(text: String) {
            self.userNamesArray = []
            if text.count > 0 {
                let ending = text + "\u{f8ff}"
                let databaseRef = self.ref.child("users")
                databaseRef.queryOrdered(byChild: "Name")
                    .queryStarting(atValue: text)
                    .queryEnding(atValue: ending)
                    .observeSingleEvent(of: .value, with: { snapshot in
                        for child in snapshot.children {
                            let childSnap = child as! DataSnapshot
                            let userName = childSnap.childSnapshot(forPath: "Name").value as! String
                            self.userNamesArray.append(userName)
                        }
                        print(self.userNamesArray) //here you would call tableView.reloadData()
                    })
            }
        }
    }
    

    That's it other than assigning self.ref to my Firebase. My structure is:

    users
      uid_0
        name: "Frank"
      uid_1
        name: "Fred"
      uid_2
        name: "Finay"
    

    etc when I type in the search field 'F' I get the following output

    ["Frank", "Fred", "Friday"]
    

    then when I type 'Fr', I get the following output

    ["Frank", "Fred"]
    

    So as you can see, it works. If it's not working in your case, you may not have your tableView connected correctly or some other issue unrelated to the search.

    Now, I am not using a tableView but simply printing name strings to the console so you would need to do a tableView.reloadData() in the place of my print statement.

    0 讨论(0)
提交回复
热议问题