ios - 嵌套请求的完成 block

标签 ios swift firebase request completion

我正在尝试为嵌套请求构建带有完成 block 的方法。问题在于,完成 block 提前捕获了父请求(这意味着子请求尚未实际完成)。到目前为止,除了我在下面的示例中所做的之外,我还没有找到一种方法让子请求与父请求进行通信(即计算已完成的子请求数量并将其与预期数量进行比较)请求数)。

下面的示例针对 Firestore 数据库进行操作。想象一下,用户有多个纸牌游戏(牌组),每个游戏都有多张牌。我非常感谢您为如何为此类案例构建更好的完成 block 提供的任何帮助:

func fetchCardsCount(uid: String, completion: @escaping (Int) -> ()) {
    let db = Firestore.firestore()


    var decksCount = Int()
    var cardsCount = Int()

    db.collection("users").document(uid).collection("decks").getDocuments { (deckSnapshot, err) in
        if let err = err {
            print("Error fetching decks for user: ", err)
        } else {
            guard let deckSnapshot = deckSnapshot else { return }

            deckSnapshot.documents.forEach({ (deck) in
                let dictionary = deck.data() as [String: Any]
                let deck = FSDeck(dictionary: dictionary)
                db.collection("users").document(uid).collection("decks").document(deck.deckId).collection("cards").getDocuments(completion: { (cardSnapshot, err) in
                    if let err = err {
                        print("Error fetching cards for deck: ", err)
                    } else {
                        guard let cardSnapshot = cardSnapshot else { return }
                        decksCount += 1
                        cardsCount += cardSnapshot.count

                        if decksCount == deckSnapshot.count {
                            completion(cardsCount)
                        }
                    }
                })
            })
        }
    }
}

最佳答案

这是使用 DispatchGroup 的解决方案,在评论中通过 @meggar 的帮助找到:

func fetchCardsCount(uid: String, completion: @escaping (Int) -> ()) {
    let db = Firestore.firestore()

    var cardsCount = Int()
    let group = DispatchGroup()

    group.enter()
    db.collection("users").document(uid).collection("decks").getDocuments { (deckSnapshot, err) in
        if let err = err {
            print("Error fetching decks for user: ", err)
        } else {
            guard let deckSnapshot = deckSnapshot else { return }

            deckSnapshot.documents.forEach({ (deck) in
                let dictionary = deck.data() as [String: Any]
                let deck = FSDeck(dictionary: dictionary)

                group.enter()
                db.collection("users").document(uid).collection("decks").document(deck.deckId).collection("cards").getDocuments(completion: { (cardSnapshot, err) in
                    if let err = err {
                        print("Error fetching cards for deck: ", err)
                    } else {
                        guard let cardSnapshot = cardSnapshot else { return }
                        cardsCount += cardSnapshot.count
                    }
                    group.leave()
                })
            })
        }
        group.leave()
    }

    group.notify(queue: .main) {
        completion(cardsCount)
    }
}

关于ios - 嵌套请求的完成 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52297728/

相关文章:

javascript - 使用 UIWebview 使用 javascript 调用 swift 函数

android - 在 Firebase 中添加应用程序时的 Flutter 选项是单独添加 IOS 和 Android 的替代方案

java - 当应用程序被杀死时如何停止接收通知?

ios - 从字符串中求和值 (componentsJoinedByString)

ios - 如何根据Apple ID在iOS中检查用户是否已购买或未使用应用内购买

ios - 如何将 iOS 中 UIButton 的状态配置更改回默认状态

ios - SwiftUI 在自定义 TextField 上切换事件/非事件线条颜色

swift - 显示本地时间设置的日期选择器

ios - Flutter 推送通知 : Unable to receive notifications in background or when app is closed

ios - Audio Session 中断后停止调用音频图渲染回调