Presenting a VideoPlayer in a sheet
.sheet(isPresented: $showVideo) {
VideoPlayerView(videoURL: postVideo.videoURL)
}
To get the video to autoplay, I've implemented the following view
struct VideoPlayerView: View {
private var player: AVPlayer
init(videoURL: URL) {
player = AVPlayer(url: videoURL)
}
var body: some View {
VideoPlayer(player: player)
.edgesIgnoringSafeArea(.all)
.onAppear {
player.play()
}
.onDisappear() {
player.pause()
}
}
}
However, checking the Memory Graph, the AVPlayer is being leaking. Omitting the onDisappear() player.pause() line, the video's sound keeps playing even after dismissing the sheet.
Going with the simpler version that doesn't keep an instance of AVPlayer doesn't have those issues, but then I lose autoplay.
struct VideoPlayerView: View {
let videoURL: URL
var body: some View {
VideoPlayer(player: AVPlayer(url: videoURL))
.edgesIgnoringSafeArea(.all)
}
}
What would be the correct way of achieving autoplay and not leaking?
(Not looking for UIViewRepresentable solution)
You can't init objects in
bodybecauseViewstructs are just values with no lifetime so any objects you init will just get lost. Instead, your objects need to be init in actions like.onAppear,.onChangeetc. and stored inside a property wrapper like@State- which essentially is another object that is given to the sameViewevery time it is re-init, which you can do as follows:In case you're wondering how on earth does SwiftUI know which
Viewto give each@Statevalue back to - it uses it's path in theViewhierarchy to identify it, so you have to take care not to move it to a different line inbody. The.idmodifier can be used to override the automatic path id.