仅在从Firebase数据库下载所有内容后才重新加载TableView数据

时间:2019-11-02 19:23:32

标签: swift firebase firebase-realtime-database firebase-storage

我已经搜索了一段时间,但是我不知道该如何处理。 我有一个Firebase数据库,其中包含一些数据以及指向存储在存储中的图像的链接。 我希望在从数据库中下载每个图像后,不仅是第一个图像,都可以重新加载UICollectionView。

newRef.observeSingleEvent(of: .value, with: { (snapshotOne) in
        for child in snapshotOne.children {
            let snap = child as! DataSnapshot
            let key = snap.key

            newRef.child(key).observeSingleEvent(of: .value, with: { (snapshotTwo) in
                for child in snapshotTwo.children {
                    let snappotto = child as! DataSnapshot
                    var imageDownloaded: UIImage?

                    if let dictionary = snappotto.value as? [String : AnyObject] {
                        let url = URL(string: dictionary["imageURL"] as! String)
                        URLSession.shared.dataTask(with: url!) { (data, response, error) in
                            if error != nil {
                                print("[Error]: \(String(describing: error))")
                                return
                            }

                            imageDownloaded = UIImage(data: data!)

                            let person = Person(name: dictionary["name"] as! String, surname: dictionary["surname"] as! String, tags: [.castana], image: imageDownloaded!)
                            self.storedData.append(person)

                            self.filteredData = self.storedData

                            DispatchQueue.main.sync {
                                UIApplication.shared.endIgnoringInteractionEvents()
                                self.collectionView.reloadData()
                                self.dismiss(animated: false, completion: nil)
                            }

                        }.resume()
                    }
                }
            }) { (error) in
                print("[Error]: \(String(describing: error))")
            }
        }
    }) { (error) in
        print("[Error]: \(error)")
    }

这是我使用的代码,但是这仅在下载第一个图像后才更新我的UICollectionView,并且它结束了IgnoringInteractionEvents-并允许用户一次又一次地重新加载数据,这导致很多图像重复。

从数据库中下载每个项目后,如何移动重新加载和endIgnoringInteractionEvents?

数据库的结构如下:

| folder
-| user
--| autoId
---| name
---| surname
---| imageUrl
--|autoId
---| name
---| surname
---| imageUrl
-| user
--| autoId
---| name
---| surname
---| imageUrl

非常感谢,NicopDev

1 个答案:

答案 0 :(得分:1)

您将观察者嵌套在嵌套数据上,这似乎是浪费代码。当您将观察者附加到某个位置时,该位置下的所有数据都已加载。

因此,您可以遍历嵌套快照以获取相同结果:

newRef.observeSingleEvent(of: .value, with: { (snapshot) in
    for child in snapshot.children {
        let userSnapshot = child as! DataSnapshot
        let userKey = userSnapshot.key

        for child in userSnapshot.children {
            let imageSnapshot = child as! DataSnapshot
            var imageDownloaded: UIImage?
            ...

解决了这个问题,让我们继续讨论真正的问题:如何检测何时加载了所有图像。

一种简单的跨平台方法是通过简单地计算已加载的图像数量,并将其与已知的图像数量进行比较。由于只有一棵只存在图像的树,因此您可以在双嵌套结构上进行迭代

let knownImageCount = 0 // we start with no knowledge of any image
let loadedImageCount = 0 // we also haven't loaded any image yet

for child in snapshot.children {
    let userSnapshot = child as! DataSnapshot
    let userKey = userSnapshot.key

    knownImageCount = knownImageCount + userSnapshot.childrenCount // we've found out about N more images

    for child in userSnapshot.children {
        let imageSnapshot = child as! DataSnapshot
        var imageDownloaded: UIImage?
        ...

        URLSession.shared.dataTask(with: url!) { (data, response, error) in

            ...

            loadedImageCount = loadedImageCount + 1 // we loaded an additional image

            if loadedImageCount == knownImageCount {
                ... // we've loaded all known images, we're done!
            }
        }.resume()