Cannot fetch data from google-cloud-firestore correctly

Viewed 53

No problems with fetching Title and Subtitle. Problems are with downloading of images and streaming the video. I really appreciate your help friends. I just want to learn how to implement it correctly and what to use, get data method or listener? Does it need grammatical changes of my code or a pair of code lines?

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()
        
        //configure cell
        cell.textLabel?.text = video.name
        cell.detailTextLabel?.text = video.lessonName
        cell.accessoryType = .disclosureIndicator
       
        
        let image = UIImage(data: video.imageData)
        cell.imageView?.image = image...
        imageName!.withRenderingMode(.alwaysTemplate)
        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 VideosViewModel which supposed to download data from firestore database and translate into local file names if I am not mistaken.

import Foundation
import FirebaseFirestore


class VideosViewModel: ObservableObject {
    @Published var videos = [Video]()
    
    private var db = Firestore.firestore()

    
    static func downloadImage(withURL url: URL, completion: @escaping (_ _image:UIImage?)->()) {
        let dataTask = URLSession.shared.dataTask(with: url) { data, url, error in
        var downloadedImage:UIImage?
            
        if let data = data {
            downloadedImage = UIImage(data: data)
            }
            
            DispatchQueue.main.async {
            completion(downloadedImage)
            }
        }
        dataTask.resume()
    }
    
   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? URL ?? ""
                let lessonName  = data["lessonName"] as? String ?? ""
                let fileURL  = data["fileURL"] as? String ?? ""
       
                print(data)


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


import Foundation

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


  [1]: https://i.stack.imgur.com/YIU5O.png
0 Answers
Related