I have an app that will play a confirmation tone if a toggle switch is set. Because the tone may be played for different actions throughout the app, I store the toggle status in the SoundManager class.
I am updating this code from ObservableObject to @Observable. (There were no errors in the ObservableObject version.) When I build the new code for @Observable, the error Cannot find '$sound' in scope appears at the UtilView toggle switch. If I remove the dollar sign I get the error Cannot convert value 'soundStatus' of type 'Bool' to expected type 'Binding', use wrapper instead. Insert $. In either case, I still have an error.
Several examples on Stackoverflow (pre @Observable) with the same error for the binding suggested using .wrappedValue or .enumberated(). It doesn't seem like I can use a standard binding since I'm checking the toggle status in multiple places throughout the app.
Here is the piece of code that activated the confirmation tone:
@Environment(SoundManager.self) private var sound
if sound.soundStatus {
sound.playSound(sound: .confirmTone)
}
struct UtilView: View {
@Environment(SoundManager.self) private var sound
var body: some View {
VStack (alignment: .leading) {
List {
// menu here
Toggle(isOn: $sound.soundStatus, // <– Error here
label: { Text("App Sound Confirmations") }
)
.toggleStyle(SwitchToggleStyle())
}
}
.listStyle(.plain)
}
}
This is the soundManager class
import AVKit
import SwiftUI
@Observable class SoundManager {
// class SoundManager: ObservableObject {
@AppStorage(StorageKeys.sound.rawValue) var soundStatus: Bool = false
var player: AVAudioPlayer?
var session: AVAudioSession = .sharedInstance()
func playSound(sound: SoundOption) {
guard let url = Bundle.main.url(forResource: sound.rawValue, withExtension: ".wav") else { return }
do {
try session.setActive(false)
try session.setCategory(.playback)
player = try AVAudioPlayer(contentsOf: url)
player?.setVolume( 0.2, fadeDuration: 0)
try session.setActive(true)
player?.play()
}
catch let error {
#if DEBUG
print("Error playing sound. \(error.localizedDescription)")
#endif
}
}
}