Swift:如何在代码执行后调用此完成块?

时间:2017-06-24 00:12:38

标签: ios swift firebase

在将用户附加到类别之前,我无法理解为什么此代码正在执行完成块。

首先,我正在尝试获取该类别。每个类别都有一个用户ID数组,它们被循环以从我的数据库中的单独位置获取用户。

以下是Firebase数据:

["Category 1": {
title = lifestyle;
users =     (
    ESKYpDMPiHW34,
    HJ8ItJDoExZMQ,
    1WDnoPy4PeQkm
);
}, "Category 2": {
title = fitness;
users =     (
    ESKYpDMPiHW3,
    HJ8ItJDoExZM,
    1WDnoPy4PeQk
);
}, "Category 3": {
title = health;
}]

这是我的代码:

class func fetchFeaturedUsers(completion: @escaping ([UserCategory]) -> Swift.Void) {
    var categories = [UserCategory]()

    let dbRef = Database.database().reference().child("categories")
    dbRef.observeSingleEvent(of: .value, with: { (snap) in

        if let dict = snap.value as? [String: Any] {
            for (_, value) in dict {

                if let category = value as? [String:Any] {

                    let title = category["title"] as? String
                    let newCategory = UserCategory(title: title?.capitalized, users: [User]())
                    categories.append(newCategory)

                    if let users = category["users"] as? [String] {
                        for id in users {
                            User.fetchUser(userId: id, completion: { (newUser) in
                                newCategory.users?.append(newUser)
                            })
                        }
                    }
                }
            }
        }
        DispatchQueue.main.async {
            completion(categories)
        }
    })
}

1 个答案:

答案 0 :(得分:1)

问题是你的User.fetchUser方法是在另一个线程中完成的异步调用。要解决此问题,您可以创建DispatchGroup,等待所有调用完成后再调用completion,如下所示:

class func fetchFeaturedUsers(completion: @escaping ([UserCategory]) -> Swift.Void) {
    var categories = [UserCategory]()
    let dispatchGroup = DispatchGroup()

    let dbRef = Database.database().reference().child("categories")
    dbRef.observeSingleEvent(of: .value, with: { (snap) in

        if let dict = snap.value as? [String: Any] {
            for (_, value) in dict {

                if let category = value as? [String:Any] {

                    let title = category["title"] as? String
                    let newCategory = UserCategory(title: title?.capitalized, users: [User]())
                    categories.append(newCategory)

                    if let users = category["users"] as? [String] {
                        for id in users {
                            dispatchGroup.enter()
                            User.fetchUser(userId: id, completion: { (newUser) in
                                newCategory.users?.append(newUser)
                                dispatchGroup.leave()
                            })
                        }
                    }
                }
            }
        }

        dispatchGroup.notify(queue: DispatchQueue.global(qos: .background)){
            completion(categories)                
        }
    })
}

您可以在documentation中了解有关DispatchGroup的更多信息。