Hello, I'm working on an SwiftUI iOS app that shows a list of timers. When the timer is up then I pop up an alert struct. The user hits "ok" to dismiss the alert. I am trying to include an alarm sound using AVFoundation. I can get the sounds to play if I change the code to play when a button clicks so I believe I have the url path correct. But I really want it to play during the alert pop up. I have not been able to find examples where this is done using an alert so I suspect I need a custom view but thought I'd try the alert route first. Anyone try this before?
@State var audioPlayer: AVAudioPlayer?
.alert(isPresented: $showAlarmAlert) {
playSound() -- Calls AVFoundation
return Alert(title: Text("Time's Up!"))
}
func playSound() {
let alertSoundPath = Bundle.main.url(forResource: "classicAlarm", withExtension: "mp3")!
do {
audioPlayer = try AVAudioPlayer(contentsOf: alertSoundPath)
audioPlayer?.play()
}
catch {
appData.logger.debug("Error playing sound: \(alertSoundPath)")
}
}
There is effectively a problem, no sound.
I tested with to different calls:
func playInputClick() {
var filePath: String?
filePath = Bundle.main.path(forResource: "ButtonTap", ofType: "wav")
let fileURL = URL(fileURLWithPath: filePath!)
var soundID:SystemSoundID = 0
AudioServicesCreateSystemSoundID(fileURL as CFURL, &soundID)
AudioServicesPlaySystemSound(soundID)
}
func playSound() {
let alertSoundPath = URL(fileURLWithPath: Bundle.main.path(forResource: "ButtonTap", ofType: "wav")!) // Bundle.main.url(forResource: "classicAlarm", withExtension: "mp3")!
do {
let audioPlayer = try AVAudioPlayer(contentsOf: alertSoundPath)
audioPlayer.play()
}
catch {
// appData.logger.debug("Error playing sound: \(alertSoundPath)")
}
}:
playSound does not work, while playInputClick() does.
So, I would change your playSound as follows:
func playSound() {
let alertSoundPath = Bundle.main.path(forResource: "classicAlarm", ofType: "mp3")!
let alertSoundURL = URL(fileURLWithPath: alertSoundPath)
var soundID:SystemSoundID = 0
AudioServicesCreateSystemSoundID(alertSoundURL as CFURL, &soundID)
AudioServicesPlaySystemSound(soundID)
}
In my tests, func are outside ContentView.
I moved playSound inside ContentView and got the runtime error (but some sound):
Modifying state during view update, this will cause undefined behavior.
So, please, show complete code so that we can reproduce (as well as the resources).