來自Geofire和其他Firebase數據庫的數據不是簡單地從數據庫中「獲取」。它是異步加載的,然後不斷同步。這改變了你的代碼流。這是最簡單的添加一些記錄上看到:
func getNearbyTrucks(){
//Query GeoFire for nearby users
//Set up query parameters
let center = CLLocation(latitude: 37.331469, longitude: -122.029825)
let circleQuery = geoFire.queryAtLocation(center, withRadius: 100)
print("Before Geoquery")
circleQuery.observeEventType(GFEventTypeKeyEntered, withBlock: { (key: String!, location: CLLocation!) in
print("In KeyEntered block ")
let newTruck = Truck()
newTruck.id = key
newTruck.currentLocation = location
self.nearbyTrucks.append(newTruck)
}) //End truckQuery
print("After Geoquery")
}
日誌的輸出將是從你可能期望不同的順序:
Geoquery
之前
後Geoquery
輸入鍵塊
輸入鍵塊
...
雖然正在從服務器檢索到的地理密鑰和用戶,代碼繼續和任何按鍵或用戶之前getNearbyTrucks()
退出返回。
解決這個問題的一種常見方法是將您認爲代碼的方式從「首先裝載卡車,然後打印第一輛卡車」改變爲「每當卡車裝上,打印第一張卡車」。
在這段代碼轉換爲:
func getNearbyTrucks(){
//Query GeoFire for nearby users
//Set up query parameters
let center = CLLocation(latitude: 37.331469, longitude: -122.029825)
let circleQuery = geoFire.queryAtLocation(center, withRadius: 100)
circleQuery.observeEventType(GFEventTypeKeyEntered, withBlock: { (key: String!, location: CLLocation!) in
let newTruck = Truck()
newTruck.id = key
newTruck.currentLocation = location
self.nearbyTrucks.append(newTruck)
print(nearbyTrucks[0].id)
}) //End truckQuery
//Execute code once GeoFire is done with its' query!
circleQuery.observeReadyWithBlock({
for truck in self.nearbyTrucks{
ref.childByAppendingPath("users/\(truck.id)").observeEventType(.Value, withBlock: { snapshot in
print(snapshot.value["name"] as! String)
truck.name = snapshot.value["name"] as! String
truck.description = snapshot.value["selfDescription"] as! String
let base64String = snapshot.value["profileImage"] as! String
let decodedData = NSData(base64EncodedString: base64String as String, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)
truck.photo = UIImage(data: decodedData!)!
})
}
}) //End observeReadyWithBlock
}
我搬到了第一輛卡車印刷成的鍵輸入事件的塊。根據您嘗試運行的實際代碼,您會將其移至不同的地方。
Firebase數據庫和Geofire自己使用的一種更可重用的方法是:將代碼塊傳遞到observeEventType withBlock:
,該代碼塊包含密鑰可用時要運行的代碼。如果採用同樣的模式,你的方法,它會變成:
func getNearbyTrucks(withBlock: (key: String) ->()){
//Query GeoFire for nearby users
//Set up query parameters
let center = CLLocation(latitude: 37.331469, longitude: -122.029825)
let circleQuery = geoFire.queryAtLocation(center, withRadius: 100)
circleQuery.observeEventType(GFEventTypeKeyEntered, withBlock: { (key: String!, location: CLLocation!) in
let newTruck = Truck()
newTruck.id = key
newTruck.currentLocation = location
self.nearbyTrucks.append(newTruck)
withBlock(nearbyTrucks[0].id)
}) //End truckQuery
//Execute code once GeoFire is done with its' query!
circleQuery.observeReadyWithBlock({
for truck in self.nearbyTrucks{
ref.childByAppendingPath("users/\(truck.id)").observeEventType(.Value, withBlock: { snapshot in
print(snapshot.value["name"] as! String)
truck.name = snapshot.value["name"] as! String
truck.description = snapshot.value["selfDescription"] as! String
let base64String = snapshot.value["profileImage"] as! String
let decodedData = NSData(base64EncodedString: base64String as String, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)
truck.photo = UIImage(data: decodedData!)!
})
}
}) //End observeReadyWithBlock
}
在這裏,你要根據你的需要withBlock()
回調移動到更合適的地方。
非常坦率的謝謝!真的很有幫助,謝謝! –