Search code examples
iosswiftuitableviewfirebasealamofireimage

Loading images from Firebase in TableViewCell Swift


Im trying to load images from my Firebase Database in my TableView Cell. Im using AlamofireImage.

@IBOutlet weak var tableView: UITableView!

var storiesArray = [Stories]()

override func viewDidLoad() {
    super.viewDidLoad()

    retrieveStories()
}

Im getting the imageDownloadURL in this function which i call in viewDidLoad()

 func retrieveStories() {

    let storiesDB = Database.database().reference().child("storyDetails")

    storiesDB.observe(.childAdded) { (snapshot) in

        let snapshotValue = snapshot.value as! Dictionary<String,String>
        let autor = snapshotValue["autor"]!
        let genre = snapshotValue["genre"]!
        let titel = snapshotValue["titel"]!
        let downloadURL = snapshotValue["imageDownloadURL"]


        let story = Stories()
        story.genre = genre
        story.titel = titel
        story.autor = autor
        story.downloadURL = downloadURL

        self.storiesArray.append(story)

        DispatchQueue.main.async(execute: {
            self.tableView.reloadData()
        })

    }
} 

After I got all that data I want to download the images from the url´s which i now have in storiesArray.downloadURL

Im doing that in cellForRowAtIndexPath

let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! StoryDetailCell

    if storiesArray[indexPath.row].downloadURL != nil {
            Alamofire.request(indexPathRow.downloadURL!).responseImage { response in
                debugPrint(response)

                print(response.request as Any)
                print(response.response as Any)
                debugPrint(response.result)

                if let image = response.result.value {
                    print("image downloaded: \(image)")
                    DispatchQueue.main.async {
                        cell.storyImage.image = image
                    }

                }
            }
        } else if indexPathRow.downloadURL == nil {
            cell.storyImage.image = #imageLiteral(resourceName: "standard")
    }

The images are only getting loaded if the cell is currently displayed. That causes many problems. One Problem is that if I scroll faster than an image loads, it will be displayed in another cell.

I would like to know how to handle a situation like this.


Solution

  • let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! StoryDetailCell
    
        cell.storyImage.image = nil
    
        cell.tag += 1
        let tag = cell.tag
    
        if storiesArray[indexPath.row].downloadURL != nil {
            Alamofire.request(indexPathRow.downloadURL!).responseImage { response in
    
                if let image = response.result.value {
                    if cell.tag == tag {
                        DispatchQueue.main.async {
                            cell.storyImage.image = image
                        }
                    }
                }
            }
        } else if indexPathRow.downloadURL == nil {
            cell.storyImage.image = #imageLiteral(resourceName: "standard")
        }