GeoFire watchReady在Swift中过早执行

时间:2019-03-28 23:26:05

标签: swift firebase geofire

在以下功能中,我正在执行初始的geofire搜索查询,希望处理找到的所有键,将它们附加到数组中,然后将整个数组发送回去。

问题是observeReady代码块执行得过早,因此发送了一个空数组(即使在该范围内找到键,也不会在第一次加载时显示任何内容)。

我了解到observeSingleEvent的调用是asynchronous并可能导致此行为,所以我的问题是,我该如何管理它并确保在执行{{1 }}在handler内调用?

observeReady

1 个答案:

答案 0 :(得分:0)

您看到的是预期的行为。确保observeReady在所有相应的observe(.keyEntered)被调用之后触发。您可以使用一些简单的日志记录语句来验证这一点:

query.observe(.keyEntered) { (key: String!, venueLocation: CLLocation!) in 
   print(".keyEntered")
}
query.observeReady {
   print(".observeReady")
}

运行此命令时,它将打印:

  

.keyEntered

     

.keyEntered

     

...

     

.observeReady

这与API的工作方式一致。但是,在.keyEntered中,您是从Firebase加载其他数据,这是异步发生的。并且.observeReady触发后,这些呼叫确实可以完成

因此,您将需要自己实现必要的同步。一种检测是否已加载所有其他数据的简单方法是对仍需要为其加载数据的所有键进行计数。因此,您+1每次添加密钥,-1每次加载场所数据:

let venuesToLoadCount = 0
query.observe(.keyEntered) { (key: String!, venueLocation: CLLocation!) in 
   venuesToLoadCount = venuesToLoadCount + 1
   self.REF_VENUES.child(key).observeSingleEvent(of: .value, with: { (snapshot) in     
        venuesToLoadCount = venuesToLoadCount - 1
        if venuesToLoadCount == 0 {
            print("All done")
        }
    }
}
query.observeReady {
    if venuesToLoadCount == 0 {
        print("All done")
    }
}