Search code examples
swiftstringuitableviewurlavplayer

Variable becomes nil after function in TableViewCell is called


I am trying to pass a URL to multiple functions inside a UITableViewCell class. In an @objc function (for handling button touches), the string variable (videoString) works perfectly. The regular function keeps finding nil when it unwraps the string.

I have already tried adjusting the optional unwrapping (?/!). No matter what I do, the function finds nil. To test this, I added @objc to the problematic function and it actually worked when I clicked the connected button.

var videoString = String()

This one works:

var parent:Home?
@objc func shareSheet() {
    let items = [URL(string: videoString)!]
    let ac = UIActivityViewController(activityItems: items, 
    applicationActivities: nil)
    parent?.present(ac, animated: true)
}

So does this:

@objc func setupPlayerView() {
    let videoURL = videoString
    if let url = URL(string: videoURL) {
        player = AVPlayer(url: url as URL)
        let playerLayer = AVPlayerLayer(player: player)
        playerLayer.frame = videoFrame.bounds
        videoFrame.layer.addSublayer(playerLayer)
        player?.play()
    } else {
        print("Invalid")
    }
}

This one doesn't...

func setupPlayerView() {
    let videoURL = videoString
    if let url = URL(string: videoURL) {
        player = AVPlayer(url: url as URL)
        let playerLayer = AVPlayerLayer(player: player)
        playerLayer.frame = videoFrame.bounds
        videoFrame.layer.addSublayer(playerLayer)
        player?.play()
    } else {
        print("Invalid")
    }
}

Cell Styling:

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)

    setupPlayerView()
    addSubview(videoFrame)
    addSubview(share)

    share.addTarget(self, action: #selector(shareSheet), for: .touchUpInside)

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

I expect setupPlayerView() to accept videoString, but it always finds nil and prints "Invalid". I think this has something to do with closures since the other function takes it correctly.


Solution

  • UPDATE

    I got it to work by declaring the URL and passing it to AVPlayer in my TableView file at cellForRowAt:

       func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) 
    -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! EpisodeCell
        let currentLastItem = episodes[indexPath.row]
        cell.episode = currentLastItem
        let videoURL = currentLastItem.videoString
        let postURL = URL(string: videoURL)
        cell.videoPlayerItem = AVPlayerItem.init(url: postURL!)
        return cell
    }
    

    And then to the function inside TableViewCell:

        func setupPlayerView() {
            self.player = AVPlayer.init(playerItem: self.videoPlayerItem)
            let playerLayer = AVPlayerLayer(player: player)
            playerLayer.frame = videoFrame.bounds
            videoFrame.layer.addSublayer(playerLayer)
            player?.play()
        }