Reputation: 1605
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
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