Перезагрузите данные TableView только после загрузки всего из базы данных Firebase Swift - PullRequest
0 голосов
/ 02 ноября 2019

Я долго искал, но не знаю, как справиться с этой проблемой. У меня есть база данных 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 Ответ

1 голос
/ 03 ноября 2019

Вы вкладываете наблюдателей во вложенные данные, что кажется пустой тратой кода. Когда вы присоединяете наблюдателя к местоположению, все данные в этом местоположении уже загружены.

Таким образом, вы можете просто зациклить вложенный снимок, чтобы получить тот же результат:

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()
...