gpt4 book ai didi

swift - 使用异步 Firebase 调用 SwiftUI

转载 作者:行者123 更新时间:2023-12-02 02:46:34 27 4
gpt4 key购买 nike

我知道 Firebase getDocument 调用是异步的,因此我试图找出如何本质上等待调用完成执行,然后继续执行其他操作。

我尝试过使用 DispatchGroup() 并进入/离开组,但我似乎无法让它正常工作。我有类似以下内容:

let myGroup = DispatchGroup()
let usersRef = self.db.collection("Users").document("Users").collection("Users")
if self.testCondition == false {
self.errorMessage = "error"
} else{
usersRef.getDocuments {(snap, err) in
myGroup.enter()
//basically getting every username
for document in snap!.documents{
let user = document["username"] as! String
let userRef = usersRef.document(user)
userRef.getDocument { (snapshot, err) in
if err != nil {
print(err)
} else {
let sample = snapshot!["sample"] as! String
if sample == 'bad' {
self.errorMessage = "error"
}
}
}
}
myGroup.leave()
}
print("what4")
//I would like it so that I can execute everything in a code block like this
//after the async call finishes
myGroup.notify(queue: .main) {
print("Finished all requests.")
//THEN DO MORE STUFF
}
}

如何修改其中的放置位置 myGroup.enter() 和 myGroup.leave(),以便在 Firebase 调用完成后,我可以继续执行代码?

谢谢!

最佳答案

这稍微解释了 DispatchGroup()

你的代码中只有一个小错误,那么它应该可以工作。确保在 Firebase getDocuments() 调用之外enter() 组。由于这已经发出请求并且需要时间,因此该过程将继续。

这个简单的小例子应该可以帮助您理解它:

func dispatchGroupExample() {

// Initialize the DispatchGroup
let group = DispatchGroup()

print("starting")

// Enter the group outside of the getDocuments call
group.enter()

let db = Firestore.firestore()
let docRef = db.collection("test")
docRef.getDocuments { (snapshots, error) in

if let documents = snapshots?.documents {
for doc in documents {
print(doc["name"])
}
}

// leave the group when done
group.leave()
}

// Continue in here when done above
group.notify(queue: DispatchQueue.global(qos: .background)) {
print("all names returned, we can continue")
}
}

等待多个异步调用时,请在异步函数中使用完成,让您在离开组后立即返回。完整例如。如下:

class Test {

init() {
self.twoNestedAsync()
}

func twoNestedAsync() {
let group = DispatchGroup() // Init DispatchGroup

// First Enter
group.enter()
print("calling first asynch")

self.dispatchGroupExample() { isSucceeded in

// Only leave when dispatchGroup returns the escaping bool

if isSucceeded {
group.leave()
} else {
// returned false
group.leave()
}
}

// Enter second
group.enter()
print("calling second asynch")

self.waitAndReturn(){ isSucceeded in

// Only return once the escaping bool comes back
if isSucceeded {
group.leave()
} else {
//returned false
group.leave()
}

}

group.notify(queue: .main) {
print("all asynch done")
}
}

// Now added escaping bool which gets returned when done
func dispatchGroupExample(completing: @escaping (Bool) -> Void) {

// Initialize the DispatchGroup
let group = DispatchGroup()

print("starting")

// Enter the group outside of the getDocuments call
group.enter()

let db = Firestore.firestore()
let docRef = db.collection("test")
docRef.getDocuments { (snapshots, error) in

if let documents = snapshots?.documents {
for doc in documents {
print(doc["name"])
}

// leave the group when succesful and done
group.leave()
}

if let error = error {
// make sure to handle this
completing(false)
group.leave()
}
}

// Continue in here when done above
group.notify(queue: DispatchQueue.global(qos: .background)) {
print("all names returned, we can continue")

//send escaping bool.
completing(true)
}
}

func waitAndReturn(completing: @escaping (Bool) -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2), execute: {
print("Done waiting for 2 seconds")
completing(true)
})
}
}

这为我们提供了以下输出:

DispatchGroup with completing and escaping output

关于swift - 使用异步 Firebase 调用 SwiftUI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62707020/

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