Cannot use instance member 'videoName' within property initializer; property initializers run before 'self' is available

Need URGENT help !!

I'm quite new to SwiftUI and I'm running into this problem as I'm trying to display a video using videoName from Model.

In the player = AVPlayer(...)(line 4), instead of finding the resource by the string "squats", I want to use videoName from Model. If I replace them I get the error "Cannot use instance member 'videoName' within property initializer; property initializers run before 'self' is available".

Can anyone please help me? This code is part of my Fitness App which is the core project of my Dissertation, hence "URGENT".

Here is my code:

struct ExercisingSessionView: View {     

    let exerciseName: String

    let videoName: String

    

    @State var player = AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: "squats", ofType: "mov")!))

    @State var isplaying = false

    @State var showcontrols = false

  

    var body: some View {

        

        CustomVideoPlayer(player: $player)

            .frame(width: 390, height: 219)

            .onTapGesture {

                self.showcontrols = true

                

            }

    }

    

    struct CustomVideoPlayer : UIViewControllerRepresentable {

        

        @Binding var player: AVPlayer

        

        func makeUIViewController(context: UIViewControllerRepresentableContext) -> AVPlayerViewController {

            

            let controller = AVPlayerViewController()

            controller.player = player

            controller.showsPlaybackControls = false

            return controller

        }

        

        func updateUIViewController(_ uiViewController: AVPlayerViewController, context: UIViewControllerRepresentableContext) {

            

        }

    }

}

Accepted Reply

you could initialize your player in the init(...) something like this:


struct ExercisingSessionView: View {
    let exerciseName: String
    let videoName: String

    @State var player: AVPlayer

    @State var isplaying = false
    @State var showcontrols = false

    init(exerciseName: String, videoName: String) {
        self.exerciseName = exerciseName
        self.videoName = videoName
        self._player = State(initialValue: AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: videoName, ofType: "mov")!)))
    }

    var body: some View {
        CustomVideoPlayer(player: $player)
            .frame(width: 390, height: 219)
            .onTapGesture {
                self.showcontrols = true
            }
    }
}

Replies

Even if you are in a hurry (should have started earlier may be 😊), take time to format code with code formatter tool (<>).

struct ExercisingSessionView: View {   
  let exerciseName: String
  let videoName: String
   
   @State var player = AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: "squats", ofType: "mov")!))
   @State var isplaying = false
   @State var showcontrols = false
  
  var body: some View {
     
    CustomVideoPlayer(player: $player)
      .frame(width: 390, height: 219)
      .onTapGesture {
        self.showcontrols = true
         
      }
  }
   
  struct CustomVideoPlayer : UIViewControllerRepresentable {
     
     @Binding var player: AVPlayer
     
    func makeUIViewController(context: UIViewControllerRepresentableContext) -> AVPlayerViewController {
       
      let controller = AVPlayerViewController()
      controller.player = player
      controller.showsPlaybackControls = false
      return controller
    }
     
    func updateUIViewController(_ uiViewController: AVPlayerViewController, context: UIViewControllerRepresentableContext) {
       
    }
  }
}

A few questions:

  • here do you set videoName,
  • how ?

To clear the error, create an init(), and give some initial value to videoName:

    let videoName: String = "" // To have it initialised. But where do you set it ?
    @State var player = AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: videoName, ofType: "mov")!))

    init() {
        player = videoName
    }

you could initialize your player in the init(...) something like this:


struct ExercisingSessionView: View {
    let exerciseName: String
    let videoName: String

    @State var player: AVPlayer

    @State var isplaying = false
    @State var showcontrols = false

    init(exerciseName: String, videoName: String) {
        self.exerciseName = exerciseName
        self.videoName = videoName
        self._player = State(initialValue: AVPlayer(url: URL(fileURLWithPath: Bundle.main.path(forResource: videoName, ofType: "mov")!)))
    }

    var body: some View {
        CustomVideoPlayer(player: $player)
            .frame(width: 390, height: 219)
            .onTapGesture {
                self.showcontrols = true
            }
    }
}