Crashed Image I have a problem when I retrieve the data via Alamofire. Here I have defined a function where the data is passed to the view controller with completion.

func getVideoDetail(video_id: String, completionHandler: @escaping (VideoDetail!) -> Void) {
   let PageURL = URL(string: "\(websiteLinks.api)/?type=get_detailss&video_id=\(video_id)")

    Alamofire.request(PageURL!).responseJSON { (response) in
        switch response.result {

        case .success:
            var getDetail: VideoDetail?
            let jsonData = response.data

            do {
                let root = try JSONDecoder().decode(DetailsData.self, from: jsonData!)
                getDetail = root.data
                //THIS IS WHERE YOUR PREVIOUS ERROR OCCURRED
            } catch {
                print("Error: \(error)")
            }
            DispatchQueue.main.async {
               completionHandler(getDetail!)
            }
        case .failure(let error):
            print(error)
        }
    }
}

And with the following code, I get the data in my ViewController.

videoModel.getVideoDetail(video_id: video_Id) { (Details) in
        self.videoDetails = Details
        self.playVideo()
    }

Here is my TableView: This Cell is a Customcell. I have register all Customcell (UINIBS) on my viewDidLoad

// REGISTER NIBS FOR THE CELLS
tableView.register(UINib(nibName: "DetailsCell", bundle: nil), forCellReuseIdentifier: "DetailsCell")



 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        switch indexPath.row {
        case 0:
            let cell = tableView.dequeueReusableCell(withIdentifier: "DetailsCell") as! DetailsCell
            cell.likeLabel.text = videoDetails!.category_name!
            cell.dislikeLabel.text = videoDetails!.category_name!
            cell.delegate = self
            return cell
        case 1:
            let cell = tableView.dequeueReusableCell(withIdentifier: "PlayerUserCell") as! PlayerUserCell
            return cell
        default:
            let cell = tableView.dequeueReusableCell(withIdentifier: "newestCell") as! NewestCell
            return cell

        }
    }

But if I now start the application and select a cell, the program crashes. What am I doing wrong here?

This is my didSelectRow code on my HomeController. I pass here the video_id for the getDetails function:

    public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let playerVC = storyboard.instantiateViewController(withIdentifier: "playervc") as! PlayerVC
    playerVC.videoURL = URL(string: featuredVideos[indexPath.row - 2].video_location!)
    playerVC.video_Id = featuredVideos[indexPath.row - 2].video_id
    playerVC.commentVideoId = featuredVideos[indexPath.row - 2].id
    self.present(playerVC, animated: true, completion: nil)
}
3

There are 3 best solutions below

0
On

replace like this;

if let data = jsonData {
    let root = try? JSONDecoder().decode(DetailsData.self, from: data)
    getDetail = root.data
}

if your jsondata is nil it will crash your application, will not be held in catch.

Btw, you should stop forcing variables. Thats not safe. Use if or guard let to prevent crashes.

0
On
      there is nil  `incategory_name` or  `category_name`

use like this

 cell.likeLabel.text = videoDetails!.category_name ?? "" 
 cell.dislikeLabel.text = videoDetails!.category_name ?? "" 
0
On

I have solved this problem.

I loaded the details directly into CustomCell file and then loaded the UI with a didSet. The code looks like this.

DetailCell:

class DetailsCell: UITableViewCell {
// Temp Helper for Like Video
var like = false
var unlike = false
var likeDislike = LikeDislikeHelper()
var videoModel = VideoModel()

var videoDetails: VideoDetail! {
    didSet {
        updateUI()
    }
}

weak var delegate: DetailsCellDelegate?
@IBOutlet weak var likeButton: AnimatableButton!
@IBOutlet weak var dislikeButton: AnimatableButton!
@IBOutlet weak var shareButton: AnimatableButton!
@IBOutlet weak var playlistButton: AnimatableButton!

@IBOutlet weak var likeLabel: UILabel!
@IBOutlet weak var dislikeLabel: UILabel!

override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code

}

func getDetails(video_id: String) {
    videoModel.getVideoDetail(video_id: video_id) { (Details) in
        self.videoDetails = Details
    }
}

func updateUI() {
    self.likeLabel.text = "\(videoDetails.likes)"
    self.dislikeLabel.text = "\(videoDetails.dislikes)"
}

ViewController:

 let cell = tableView.dequeueReusableCell(withIdentifier: "DetailsCell") as! DetailsCell
            cell.checkIsLiked(commentVideoId: commentVideoId)
            cell.getDetails(video_id: video_Id)
            cell.delegate = self
            return cell

Thanks to all who helped