Home > Software engineering >  Cannot download image from Cloud Firestore database
Cannot download image from Cloud Firestore database

Time:09-14

This is the tableviewController which supposed to show image in each row but it does not. enter image description here When I run the application on simulator it starts and displays the table view with titles and subtitles but images. I also attach the screenshots of simulator with some prints and of the structure of the database.enter image description here

import UIKit
import AVKit
import AVFoundation
import FirebaseFirestore
import Combine

class ListOfVideoLessonsTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    
    let pinchGesture = UIPinchGestureRecognizer()
    
    private var viewModel = VideosViewModel()
    private var cancellable: AnyCancellable?
    var player = AVPlayer()
    var playerViewController = AVPlayerViewController()
    
    @IBOutlet var table: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
 
        self.viewModel.fetchData()
        
        self.title = "Video Lessons"
        
        table.delegate = self
        table.dataSource = self
        
        cancellable = viewModel.$videos.sink { _ in
            DispatchQueue.main.async{
                
                self.table.reloadData()
        }
    }
}

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("videos count = ", viewModel.videos.count)
        return viewModel.videos.count
}
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        let video = viewModel.videos[indexPath.row]
        tableView.tableFooterView = UIView()
        
        cell.textLabel?.text = video.name
        cell.detailTextLabel?.text = video.lessonName
        cell.accessoryType = .disclosureIndicator
        let image = UIImage(named: video.imageName)
        cell.imageView?.image = image
        let backgroundView = UIView()
        backgroundView.backgroundColor = UIColor(named: "VideoLessonsCellHighlighted")
        cell.selectedBackgroundView = backgroundView
        cell.textLabel?.font = UIFont(name: "Helvetica-Bold", size: 14)
        cell.detailTextLabel?.font = UIFont(name: "Helvetica", size: 12)
        
        return cell
}
    

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 100
}
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        
        playVideo(at: indexPath)
}
    
     func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath) {
        if let cell = tableView.cellForRow(at: indexPath) {
            cell.contentView.backgroundColor = UIColor(named: "VideoLessonsCellHighlighted")
            cell.textLabel?.highlightedTextColor = UIColor(named: "textHighlighted")
            cell.detailTextLabel?.highlightedTextColor = UIColor(named: "textHighlighted")
    }
}

     func tableView(_ tableView: UITableView, didUnhighlightRowAt indexPath: IndexPath) {
        if let cell = tableView.cellForRow(at: indexPath) {
            cell.contentView.backgroundColor = nil
            
    }
}
    
        func playVideo(at indexPath: IndexPath){
            let selectedVideo = viewModel.videos[indexPath.row]
            let videoURL = URL(string: selectedVideo.fileURL)
            player = AVPlayer(url: videoURL!)
            playerViewController.player = player
            
            
          self.present(playerViewController, animated: true, completion: {
                self.playerViewController.player?.play()
        })
           
    }
}

This is the viewModel which I believe should download images and pass to the tableview cells.

import Foundation
import FirebaseFirestore


class VideosViewModel: ObservableObject {

@Published var videos = [Video]()
private var db = Firestore.firestore()

func fetchData() {
    db.collection("videos").addSnapshotListener { [self] (querySnapshot, error) in
    guard let documents = querySnapshot?.documents else {
    print("No Documents")
    return
}

self.videos = documents.map { (queryDocumentSnapshot) -> Video in
    let data = queryDocumentSnapshot.data()
                
    let name = data["name"] as? String ?? ""
    let imageName = data["imageName"] as? String ?? ""
    let lessonName  = data["lessonName"] as? String ?? ""
    let fileURL  = data["fileURL"] as? String ?? ""
              
    print(data)


    return Video(name: name , imageName: imageName , lessonName: lessonName, fileURL: fileURL )
                
              
            }
        }
    }
}

And this the struct of the video

import Foundation

struct Video {
    var name: String
    var imageName: String
    var lessonName: String
    var fileURL: String
}

CodePudding user response:

Does an image with that 'video.imageName' exist within the app?

let image = UIImage(named: video.imageName)
cell.imageView?.image = image

you should be download from firebase storage.

use to

guard let url = URL(string: video.imageName) else {return}
URLSession.shared.dataTask(with: URL, completionHandler: (Data?, URLResponse?, Error?) -> Void)

CodePudding user response:

the first answer is one option however you will encounter the frozen screen while scrolling the UITableView. if you want to void that. Then you can use SDWebImage SDK

import UIKit
import SDWebImage

class ListOfVideoLessonsTableViewController {

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        let video = viewModel.videos[indexPath.row]
        tableView.tableFooterView = UIView()
        
        cell.textLabel?.text = video.name
        cell.detailTextLabel?.text = video.lessonName
        cell.accessoryType = .disclosureIndicator
        let image = UIImage(named: video.imageName)
        cell.imageView?.sd_imageIndicator = SDWebImageActivityIndicator.gray
        cell.sd_setImage(with: URL(string: stringWithoutWhitespace), placeholderImage: UIImage())      
        let backgroundView = UIView()
        backgroundView.backgroundColor = UIColor(named: "VideoLessonsCellHighlighted")
        cell.selectedBackgroundView = backgroundView
        cell.textLabel?.font = UIFont(name: "Helvetica-Bold", size: 14)
        cell.detailTextLabel?.font = UIFont(name: "Helvetica", size: 12)
        
        return cell
    }
}   

  • Related