Getting value 'nil' after didSet

It has been 5 days since I'm trying to solve this problem. I have a collectionViewCell in which I have parsed an XML URL data which includes a name and an ID. Now when I tap the cell, I want to load a UIView with an AVPlayer in it. To play the file, I have to use a different URL but with the id that I have parsed in that cell. Here is my

didSelectItem func
:


funccollectionView(_ collectionView: UICollectionView, didSelectItemAtindexPath: IndexPath) {

        let playerView = PlayerView()
        playerView.item = items?[indexPath.item]

        let playerLauncher = PlayerLauncher()
        playerLauncher.showPlayer()
    }


This is my PlayerLauncher file:


import UIKit
import AVFoundation
class PlayerView: UIView {

    var itemId: String?

    var item: Item? {
        didSet {
            itemId = item?.itemId
        }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
   
        backgroundColor = UIColor.black
        setupPlayer()
    }

    var player: AVPlayer?

    func setupPlayer() {
   
        if let url = URL(string: "h t t p : //xample . com/play . m3u/id=\(itemId)")
            player = AVPlayer(url: url)
            print(url)
            let playerLayer = AVPlayerLayer(player: player)
            self.layer.addSublayer(playerLayer)
            playerLayer.frame = self.frame
       
            player?.play()
        }
    }
   
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
class PlayerLauncher: NSObject {

    func showPlayer() {
   
        if let keyWindow = UIApplication.shared.keyWindow {
            let view = UIView(frame: keyWindow.frame)
            view.backgroundColor = UIColor.white
            view.frame = CGRect(x: 0, y: keyWindow.frame.height - 50, width: view.frame.width, height: 50)
            let playerFrame = CGRect(x: 0, y: 0, width: keyWindow.frame.width, height: keyWindow.frame.height)
            let playerView = PlayerView(frame: playerFrame)
            view.addSubview(playerView)
            keyWindow.addSubview(view)
            UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
                view.frame = keyWindow.frame
            }, completion: nil)
        }
    }
}


I can print the id from

didSet(by putting a breakpoint there)
but when in setupPlayer() method it still shows
id = nil
when I select the item. How can I get the properties set in
didSet
in
init
or
startPlaying()
func?

There is something I do not understand in the logic.


You select a cell.

- func collectionView creates a PlayerView, which calls init()

At this time, ID is still nil

- init() calls setUpPlayer, with a nil ID

- collectionView sets the item: ID is now valid, but setupPlayer is done and will never be called again.


Note: you have a typo : funccollectionView vs func collectionView


I've not tested the following, so you may have some fine tuning to do.


You should probably create a convenience init for PlayerView :

convenience init(item: Item)
     self.init()
     self.item = item
     setupPlayer()
}

and change init(frame):

   override init(frame: CGRect) {
        super.init(frame: frame)

        backgroundColor = UIColor.black
    }

change collectionView

func collectionView(_ collectionView: UICollectionView, didSelectItemAtindexPath: IndexPath) {

     // You should test if items is nil
     if items = nil { return }
     let playerView = PlayerView(items![indexPath.item])
       //  playerView.item = items?[indexPath.item]

        let playerLauncher = PlayerLauncher()
        playerLauncher.showPlayer()
    }


Thanks to report if that works.

didSet
isn't called during initialization, only afterwards. So your print in didSet comes from some call that is made after initialization (not from setupPlayer as called from init).
Getting value 'nil' after didSet
 
 
Q