nonamorando
nonamorando

Reputation: 1605

SwiftUI: AVAudioPlayer does not stop

I have an AVAudioPlayer with some key data in an Observable Object:

class Player: ObservableObject {
    var data: Data?
    var player: AVAudioPlayer?
    
    init() {}
    
    func play(audioData: Data) {
        self.stop()
        
        // Set the data for the player
        self.data = audioData
        
        do {
            self.player = try AVAudioPlayer(data: audioData)
        } catch {
            debugPrint("error")
        }
        
        // Play with the audio if it exists
        player?.prepareToPlay()
        player?.play()
    }
    
    func pause() {
        player?.pause()
    }
    
    func stop() {
        player?.stop()
        player?.currentTime = 0
    }
}

The stop() function is not called player?.stop, because for an unknown reason, the AVAudioPlayer is nil (even though it's playing the audio).

In the view, when I play it, I want to mutate the struct containing the data. The view looks like this:

struct MainView: View {
  @ObservedObject var player = Player()
  var body: some View { 
    ForEach(audioDataList) { audioData in 
      SubView(audioData: audioData).environmentObject(player)
    }
  }
} 

struct SubView: View {
  @EnvironmentObject var player: Player
  var audioData: AudioData
  var body: some View {
    Text("Play or stop")
      .onTapGesture {
        player.play()
        audioData.mutateAudioDataStruct()
      }
  } 
}

Why does the audio not stop playing when I'm calling player.play()? I have the stop() function in there and the AVAudioPlayer is clearly not nil if it's playing audio.

Upvotes: 0

Views: 409

Answers (1)

jnpdx
jnpdx

Reputation: 52565

If you want to mutate a struct owned by a SwiftUI View, it should be be a @State variable -- trying to mutate non-@State variables will at-best not compile (the compiler should tell you that you Cannot use mutating member on immutable value: 'self' is immutable) and, at worst, (if you've somehow found a way around that compiler error), cause unexpected consequences.

Future readers, see the comments on the original question for a more detailed explanation of how this conclusion was reached

Upvotes: 1

Related Questions