Hibernia Hibernia - 2 months ago 16
iOS Question

Stopping a query to firebase?

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

if searchBar.text == nil || searchBar.text == "" {

inSearchMode = false

} else {

if allInterestsArray.contains(searchBar.text!.lowercaseString) {

ref.child(searchBar.text!.lowercaseString).child("users")

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) { () -> Void in

print("this should be running")
print(searchBar.text!.lowercaseString)

let handle = roomsRef.observeSingleEventOfType(.Value, withBlock: { (snapshot: FIRDataSnapshot) in

print(snapshot.value)

if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {
for snap in snapshots {

print(snap)
}

}

})
}
}
else {
print("doesn't exist")
}


}
}


I'm running a query to my firebase database when my searchBar.text is equal to something in my allInterestsArray. This is being checked for on keystroke, and I'm using dispatch_after to prevent a query being sent until the user is probably done typing.

What is happening is if I have the item in my array of "Dog" and the user gets to "dog" and then types in an "s" which makes it "dogs"..the query is still being sent off for dog and then again for dogs, so I need to cancel the query up at the top of my textDidChange func I think so on each keystroke it's being canceled, and only after a second of no typing is the query being sent off.

I was thinking of using removeHandle but I don't think that's what that's meant to be used for?

Example:

If my array = ["dog","dogs","doggies"]

The user types quickly enough so there's not a full 1 second between any two letters (one second because of the dispatch_after time I set) and they type in "dogs".. the query for dog should not have gone off, only for "dogs".

Answer

This problem could be solved using a global variable called "keepSearching" as below :

EDIT : I've now also used NSTimer to give a one-second gap for "keepSearching" to be false.

var keepSearching: Bool = true
var timer = NSTimer()
func timerAction() {
    keepSearching = false
}
func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {

if searchBar.text == nil || searchBar.text == "" {
    inSearchMode = false

} 
else if(keepSearching) {

    if allInterestsArray.contains(searchBar.text!.lowercaseString) {


      // just in case user keeps on typing, invalidate the previous timer, before it happens.
      timer.invalidate()

      // schedule a new timer everytime.
      timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(timerAction), userInfo: nil, repeats: false)

      ref.child(searchBar.text!.lowercaseString).child("users")

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) { () -> Void in

            print("this should be running")
            print(searchBar.text!.lowercaseString)

            let handle = roomsRef.observeSingleEventOfType(.Value, withBlock: { (snapshot: FIRDataSnapshot) in

                print(snapshot.value)

                if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {
                    for snap in snapshots {

                        print(snap)
                    }

                }

            })
        }
    }
    else {
        print("doesn't exist")
    }
}