gpt4 book ai didi

ios - 在使用 Swift 的 iOS 应用程序中使用 DispatchQueue 等待数据从 Cloud Firestore 返回时遇到问题

转载 作者:行者123 更新时间:2023-11-30 10:24:18 24 4
gpt4 key购买 nike

我尝试使用 DispatchQueue 让我的代码等待查询从 Cloud Firestore 检索到我需要的结果,然后再继续执行,但就是无法让它正常工作。在下面的代码中,我试图让它等待,直到数据被检索并存储在 zoneMarkerArray 中,然后打印出结果。

我已经按照我希望的顺序对它打印的每一行进行了编号,正如您将在输出中看到的那样,它在继续之前不会等待 Firestore 结果。

这是我的代码:

let zones = self.db.collection("zones")

let zonesQuery = zones.whereField("start", isGreaterThan: lowerLimit).whereField("start", isLessThan: upperLimit)

print("1. zones Query has been defined")

//pass zonesQuery query to getZoneMarkers function to retrieve the zone markers from Firestore
getZoneMarkers(zonesQuery)

print("6. Now returned from getZoneMarkers")


func getZoneMarkers(_ zonesQuery: Query) -> ([Double]) {
print("2. Entered getZoneMarkers function")
DispatchQueue.global(qos: .userInteractive).async {

zonesQuery.getDocuments() { (snapshot, error) in

if let error = error {
print("Error getting zone markers: \(error)")
} else {

print("3. Successfully Retrieved the zone markers")
var result: Double = 0.0

for document in snapshot!.documents {

print("Retrieved zone marker is \(document["start"]!)")
self.zoneMarkerArray.append(document["start"]! as! Double)
print("4. Looping over zone marker results")

}
}
}

DispatchQueue.main.async {
//I want this the printCompleted function to print the result AFTER the results have been retrieved
self.printCompleted()

}
}

return self.zoneMarkerArray

}


func printCompleted() {
print("5. Looping now completed. Result was \(zoneMarkerArray)")
}

这是打印出来的输出:

  1. 区域查询已定义
  2. 进入 getZoneMarkers 函数
  3. 现在从 getZoneMarkers 返回
  4. 循环现已完成。结果是[0.0]
  5. 成功检索区域标记
  6. 循环区域标记结果
  7. 循环区域标记结果检索到的区域标记为 12.0
  8. 循环区域标记结果

感谢您的帮助!

编辑:如果其他人也遇到这个问题,这里是我根据收到的反馈最终整理的工作代码。如果您发现如何进一步改进,请随时提出批评:

let zones = self.db.collection("zones")

let zonesQuery = zones.whereField("start", isGreaterThan: lowerLimit).whereField("start", isLessThan: upperLimit)


print("1. zones Query has been defined")

//pass zonesQuery query to getZoneMarkers function to retrieve the zone markers from Firestore
getZoneMarkers(zonesQuery)

func getZoneMarkers(_ zonesQuery: (Query)) {
print("2. Entered getZoneMarkers function")
zoneMarkerArray.removeAll()

zonesQuery.getDocuments(completion: { (snapshot, error) in
if let error = error {
print("Error getting zone markers: \(error)")
return
}

guard let docs = snapshot?.documents else { return }

print("3. Successfully Retrieved the zone markers")


for document in docs {

self.zoneMarkerArray.append(document["start"]! as! Double)
print("4. Looping over zone marker results")

}

self.completion(zoneMarkerArray: self.zoneMarkerArray)

})
}


func completion(zoneMarkerArray: [Double]) {
print("5. Looping now completed. Result was \(zoneMarkerArray)")

}

最佳答案

从问题来看,似乎不需要任何 DispatchQueue。 Firestore 异步,因此数据仅在 firebase 函数后面的闭包内有效。此外,UI 调用在主线程上处理,而网络则在后台线程上处理。

如果您想等待从 Firestore 加载所有数据,则可以在 Firestore 调用之后的闭包内完成。例如,假设我们有一个区域集合,其中包含存储开始和停止指示器的文档

zones
zone_0
start: 1
stop: 3
zone_1
start: 7
stop: 9

对于此示例,我们将在元组类数组中存储每个区域的开始和停止

var tupleArray = [(Int, Int)]()

以及要在区域中读取的代码,填充 tupleArray,然后执行“下一步” - 在本例中打印它们。

func readZoneMarkers() {
let zonesQuery = self.db.collection("zones")
zonesQuery.getDocuments(completion: { documentSnapshot, error in
if let err = error {
print(err.localizedDescription)
return
}

guard let docs = documentSnapshot?.documents else { return }

for doc in docs {
let start = doc.get("start") as? Int ?? 0
let end = doc.get("end") as? Int ?? 0
let t = (start, end)
self.tupleArray.append(t)
}

//reload your tableView or collectionView here,
// or proceed to whatever the next step is
self.tupleArray.forEach { print( $0.0, $0.1) }
})
}

和输出

1 3
7 9

由于 Firebase 的异步特性,您无法从闭包“返回”,但如果需要从闭包“传回”数据,您可以利用完成处理程序。

关于ios - 在使用 Swift 的 iOS 应用程序中使用 DispatchQueue 等待数据从 Cloud Firestore 返回时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60159438/

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