1

The code below pulls from the firebase database 30kb photos but has a delay of over 15 seconds while downloading 10 photos. Ive tried using the FirebaseStorageUI cell.cellImageView.sd_setImage(with: downloadURL, completed:nil) but it doesnt allow me acess the image size directly afterwards resulting in the program crashing. Is there any way to speed up the downloading and loading of images into cells.

NOTE: THIS QUESTION IS NOT A DUPLICATE, Ive tried using the google FirebaseStorageUI libraries sd_setImage(with: downloadURL, completed:nil) which was a suggested solution but it does not load the image in time for me to access the image size and adjust the row height accordingly. When I go access the image property of the imageView which the sd_setImage(with: downloadURL, completed:nil) is acting the imageView returns nil.

import UIKit
import Firebase
import FirebaseStorageUI

class TableViewController: UITableViewController {
var images:[UIImage]! = [#imageLiteral(resourceName: "rininger_2.jpg")]
var imageURLS:[String] = [String]()
var listener:ListenerRegistration?

override func viewDidLoad() {
    super.viewDidLoad()

    /////////
    listener = Firestore.firestore().collection("Posts").addSnapshotListener{
        querySnapshot, error in
        guard let snapshot = querySnapshot else {
            print("Error fetching snapshots: \(error!)")
            return
        }
        snapshot.documentChanges.forEach { diff in
            if (diff.type == .added) {
                print("New data: \(diff.document.data())")
            }
            if (diff.type == .modified) {
                print("Modified city: \(diff.document.data())")
            }
            if (diff.type == .removed) {
                print("Removed city: \(diff.document.data())")
            }
            // self.numberOfRows = snapshot.count
            // Parse each post


            //self.labels.append(newLabel)


            //Update TableView
            DispatchQueue.main.async {
                //This would reload everything creating a flash
                //self.tableView.reloadData()
                guard let newImageURL = diff.document.data()["imageDownloadURL"] as? String else{
                    print("Failed to get image download URL")
                    return
                }
                //let newLabel = Post(snapshot:diff.document)
                print("downloadURL: \(newImageURL)")
                self.imageURLS.insert(newImageURL, at: 0)
                let indexPath = IndexPath(row: 0, section: 0)
                self.tableView.insertRows(at: [indexPath], with: .top)
                //self.tableView.reloadData()
            }
        }
    /////////
    }

}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return imageURLS.count
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Reuse", for: indexPath) as! TableViewCell

    // Configure the cell...

    ///////////////////////

        let downloadURL = URL(string: self.imageURLS[indexPath.row])

            //cell.cellImageView.sd_setImage(with: downloadURL, completed:nil)
            //cell.cellImageView.image = self.images[indexPath.row]

    do{
        let imageData = try Data(contentsOf: URL(string:(self.imageURLS[indexPath.row]))!)
        cell.cellImageView.image = UIImage(data: imageData)

    }
    catch{
        print("unable to load data: \(error)")
    }

            cell.cellImageView.contentMode = .scaleAspectFit
            let aspectRatio = Float((cell.cellImageView?.image?.size.width)!/(cell.cellImageView?.image?.size.height)!)
            tableView.rowHeight = CGFloat(Float(UIScreen.main.bounds.width)/aspectRatio)

    ///////////////////////
    return cell
}
}
user372382
  • 183
  • 9
  • Where does the time go? Is it in download the documents from Cloud Firestore? Or is it in downloading the actual images? – Frank van Puffelen Jan 13 '18 at 18:29
  • @FrankvanPuffelen I believe it’s in downloading the images based on the console output – user372382 Jan 13 '18 at 18:30
  • Never download data from the Internet on the main queue. Bad, bad, bad. – rmaddy Jan 13 '18 at 18:35
  • @rmaddy Duly noted, it won’t happen again. I’ve removed the dispatchQueue from the initial download but loading the images into the table view is still very slow – user372382 Jan 13 '18 at 18:47
  • Please see the linked question and its answers. – rmaddy Jan 13 '18 at 18:49
  • @rmaddy I have looked at this answer before the answer suggests using a library similar the google FirebaseStorageUI, as I mentioned I have tried using a function called sd_setImage(with: downloadURL, completed:nil) but it is not returning the image value to the UIImageView before I try to access the image size to calculate the aspectFit on the next line. – user372382 Jan 13 '18 at 18:55
  • Images must be downloaded asynchronously to avoid the slowdowns and choppiness. And never set a table view's `rowHeight` in `cellForRowAt`. That's a big problem too. – rmaddy Jan 13 '18 at 19:06
  • @rmaddy thank you for all of your advise, where should row height be set then, in my code I need to be able to access the image size contained in the cells imageView in order to determine the cell height – user372382 Jan 13 '18 at 23:31

0 Answers0