停止查询firebase?

时间:2016-09-11 19:22:47

标签: ios swift firebase firebase-realtime-database

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")
        }


    }
}

当我的searchBar.text等于我的allInterestsArray中的内容时,我正在向我的firebase数据库运行查询。这是在击键时检查的,我使用dispatch_after来阻止在用户输入完成之前发送查询。

发生的事情是,如果我的数组中有" Dog"并且用户到达" dog"然后键入" s"这使得它"狗" ..查询仍被发送给狗,然后再为狗发送,所以我需要在textDidChange func的顶部取消查询我想是这样每次击键它& #39; s被取消,只有在没有打字的情况下,才会发送查询。

我正在考虑使用removeHandle,但我不认为这意味着什么?

示例:

如果我的阵列= ["狗","狗","狗狗"]

用户输入的速度足够快,因此任意两个字母之间的时间间隔不足1秒(因为我设置了dispatch_after时间后一秒钟),他们输入"狗" ..查询对于狗来说,不应该只为#34;狗"。

2 个答案:

答案 0 :(得分:1)

可以使用名为“keepSearching”的全局变量解决此问题,如下所示:

编辑:我现在也使用NSTimer为“keepSearching”提供一秒钟的差距。

{{1}}

答案 1 :(得分:0)

您可以添加一个在每次提交dispatch_after块时递增的属性,并检查该值是否与当前值相对应。通过这种方式,您可以判断是否应该启动请求。这里你的控制器类可能是这样的(只包括这个问题的相关部分):

class MyController: <base class, protocols> {

    var requestsCounter = 0

    func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
        // mark that a new request is made
        self.requestsCounter++

        // save the number in a local var to be used when the block
        // actually executes
        let currentCounter = self.requestsCounter

        if searchBar.text == nil || searchBar.text == "" {
            inSearchMode = false
        } else {
            dispatch_after(...) { () -> Void in

            // if another dispatch_after was submitted, then the value of the 
            // currentCounter local variable won't match the property value,
            // so we should no longer proceeed
            guard currentCounter == self.requestsCounter  else { return }

            // ... the original code here
        }
    }

它是如何运作的:

  • 第一次调用委托方法时,它会递增requestsCounter属性,所以现在它的值为1
  • 此值(1)保存到局部变量currentCounter中,其值由dispatch_after闭包捕获。
  • 如果在dispatch_after执行闭包之前调用委托方法,则requestsCounter将递增为2,并且将创建具有该值的新currentCounter变量,并且由第二个dispatch_after关闭
  • 捕获
  • 现在当第一个dispatch_after闭包执行时,捕获的currentCounter值将保持为1,但self.requestsCounter将为2,因此闭包将返回而不进行实际工作
  • 相同的逻辑适用于后续请求,searchBar: textDidChange:委托方法将在每次requestsCounter属性时递增,这反过来将使先前调度的闭包无效,因为每个属性都捕获{{1}的旧值1}} property。