gpt4 book ai didi

swift - 使用 Geofire/Firebase 组装用户列表

转载 作者:可可西里 更新时间:2023-11-01 00:59:01 32 4
gpt4 key购买 nike

我有一个名为 User 的类,它具有使用 GeoFire 获取附近所有食品卡车的功能。我使用 observeReadyWithBlock 获取 GeoFire 返回的卡车 ID,并使用 Firebase 获取他们的其余信息。但是,当我在添加名称和描述后从我的 Truck 对象数组中访问其中一辆卡车时,xCode 似乎告诉我该数组是空的。

我计划在其他 Controller 类中使用这个附近卡车数组来填充向用户显示所有附近卡车和一些基本信息的表格。

我怎样才能正确地填充我的卡车数组,以及根据下面的代码我可能会犯什么错误。非常感谢!

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)

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

print(nearbyTrucks[0].id)
//This line gives the error that the array index is out of range
}

最佳答案

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

日志输出的顺序与您预期的顺序不同:

Before Geoquery

After Geoquery

In KeyEntered block

In KeyEntered block

...

当从服务器检索 Geo-keys 和用户时,代码继续执行并且 getNearbyTrucks() 在返回任何 key 或用户之前退出。

处理此问题的一种常见方法是将您对代码的看法从“首先装载卡车,然后打印第一辆卡车”更改为“每当卡车装载时,打印第一辆”。

在代码中这转化为:

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
}

我已将第一辆卡车的打印移到键输入事件的 block 中。根据您尝试运行的实际代码,您会将其移动到不同的位置。

一种更可重用的方法是 Firebase 数据库和 Geofire 自己使用的方法:将一个 block 传递到 observeEventType withBlock: 并且该 block 包含在 key 可用时要运行的代码。如果你对你的方法应用相同的模式,它会变成:

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() 回调移动到更合适的位置。

关于swift - 使用 Geofire/Firebase 组装用户列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38581573/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com