Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to pass image downloaded from the firebase database

I cannot have the image shown on the detailViewController which I retrieve from the firebase database.

I've tried to solve it by looking at other examples such as the one below but I couldn't get it working. (iOS + Firebase) Unable to pass the Image to the next ViewController from a UITableViewCell

This is my image service:

import Foundation
import UIKit
import IHProgressHUD

class ImageService {

     static let cache = NSCache<NSString, UIImage>()

    static func downloadImage(withURL url:URL, completion: @escaping (_ image:UIImage?, _ url:URL)->()) {
        let dataTask = URLSession.shared.dataTask(with: url) { data, responseURL, error in
            var downloadedImage:UIImage?


            if let data = data {
                downloadedImage = UIImage(data: data)
            }

            if downloadedImage != nil {
                self.cache.setObject(downloadedImage!, forKey: url.absoluteString as NSString)
            }

            DispatchQueue.main.async {
                completion(downloadedImage, url)
                IHProgressHUD.dismiss()
            }

        }

        dataTask.resume()
    }

    static func getImage(withURL url:URL, completion: @escaping (_ image:UIImage?, _ url:URL)->()) {
        if let image = cache.object(forKey: url.absoluteString as NSString) {
            completion(image, url)
        } else {
            downloadImage(withURL: url, completion: completion)
        }
    }
}

This is how I construct my collectionViewCell

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        if collectionView === self.vegatableCollectionView {

            let productCell = collectionView.dequeueReusableCell(withReuseIdentifier: "vegatable", for: indexPath) as! MainCollectionViewCell
            productCell.set(cell: veggies[indexPath.row])


            if let productImageURL = cell?.productImageURL {
                cell?.productImageURL = productImageURL
            }

            return productCell
}

This is what happens when I select a cell:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

        if collectionView == self.vegatableCollectionView {
            performSegue(withIdentifier: "showVegetableDetail", sender: veggies[indexPath.item])
}
}

This is how I segue:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        if segue.identifier == "showVegetableDetail" {

            let destination = segue.destination as! VegetableDetailViewController
            destination.selectedProduct = sender as! Product
            }
}

And finally this is my detailViewController:

    var veggies = [Product]()
    var veggieRef: DatabaseReference?
    var selectedProduct: Product?
    weak var cell:Product?

    @IBOutlet weak var headerTitle: UILabel!
    @IBOutlet weak var itemDescription: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        scrollView.delegate = self

        getTheData()

    }

    func getTheData() {

        headerTitle.text = selectedProduct?.productName
        itemDescription.text = selectedProduct?.productDescription
}
}

I simply want to get the image from the database and show it in the detailViewController.

like image 813
Burak Avatar asked Dec 08 '25 05:12

Burak


1 Answers

I would change the way that you are approaching this problem.

I would say the reason it is not working is caused by how you are downloading the image. When downloading images and setting them I have found that the easiest way to do it is using the SDWebImage library, why reinvent the wheel?

This has specialised functions which will do what you are currently trying to do manually.

The function I would focus on is:

imageView.sd_setImage(with: URL(string: "http://www.imageURL.com/path/to/image.jpg"), placeholderImage: UIImage(named: "placeholder.png"))

This function will set the image from a URL. It covers downloading the image and then setting it, whilst also allowing you to pass through a placeholder image to be shown while your image is loaded.

In this case your code would be simplified to:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    if collectionView === self.vegatableCollectionView {

        let productCell = collectionView.dequeueReusableCell(withReuseIdentifier: "vegatable", for: indexPath) as! MainCollectionViewCell
        productCell.set(cell: veggies[indexPath.row])
        productCell.imageView.sd_setImage(with: cell?.productImageURL, placeholderImage: UIImage(named: "loading_vege.png"))

        return productCell
    }
}

This simplifies everything by only requiring you to download the information from firebase including the image url. This can then be passed into the cell and loaded.

Bonus: SDWebImage also caches the image data for you. This means if you load and come back your images will be cached for a certain amount of time.

like image 173
sam_smith Avatar answered Dec 10 '25 19:12

sam_smith



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!