swiftfirebasefirebase-storageviewwillappear

Firebase Storage download not going through in the first run swift


This is the code I use to retrieve image files from Firebase storage:

    let group = DispatchGroup()
    print("starting ImageSetting")
    group.enter()
    for query in friendArray {
        if imageList[query.uid] == nil {
            print("going through iteration")
            self.profpicRef.child("profile_pic/" + query.uid + ".jpeg").getData(maxSize: 1
            * 1024 * 1024) { (data, error) in
                print("accessing image")
                if let error = error {
                    self.imageList[query.uid] = self.defaultImage
                } else {
                    self.imageList[query.uid] = UIImage(data: data!)
                }
            }
        }
    }
    group.leave()

I call this method in ViewWillAppear. I also tried ViewDIdAppear but the result did not change.

This is the result I get from calling this method on the first run

starting ImageSetting
going through iteration
going through iteration
going through iteration
going through iteration
going through iteration
going through iteration
going through iteration
going through iteration
going through iteration
going through iteration
going through iteration
going through iteration

So first run getData() is not going through. However, on second run, the function works properly and I get all the images

Is there any way to fix this issue?


Solution

  • I suspect the problem is that you're not really using dispatch group properly. The issue here is that the for loop is essentially executed and completed immediately -- yes, those callbacks will be called at a later point, but that's not the point where the code telling the dispatch group to leave.

    (Also, I don't see a notify call in your sample code, but I'm assuming that's in a part of the code that's being called later.)

    So if you're doing something in your code that's dependent upon having those images already loaded, it'll give you an error. And I suspect it probably works the second time because you're grabbing cached data, which probably does execute quick enough for your purposes.

    One way to fix it would be to make sure you're adding the dispatch group elements at the right places. Maybe something like this...

    let group = DispatchGroup()
    print("starting ImageSetting")
    for query in friendArray {
        if imageList[query.uid] == nil {
            print("going through iteration")
            group.enter()
            self.profpicRef.child("profile_pic/" + query.uid + ".jpeg").getData(maxSize: 1
            * 1024 * 1024) { (data, error) in
                print("accessing image")
                if let error = error {
                    self.imageList[query.uid] = self.defaultImage
                } else {
                    self.imageList[query.uid] = UIImage(data: data!)
                }
                group.leave()
            }
        }
    }
    group.notify(queue: .main) {
        print("Images done loading")
    }