Аудио из AVAudioPlayer не создает звука

#ios #swiftui

#iOS #swiftui

Вопрос:

Вот код, который не работает (звук успешно воспроизводится, но не издает звука):

 struct MultipleChoiceOption: View {
    let soundManager = SoundManager()

    var body: some View {
        Button(action: {
            SoundManager().playSound(name: "click.wav")
 

В то время как этот код работает:

 struct MultipleChoiceOption: View {
    let soundManager = SoundManager()

    var body: some View {
        Button(action: {
            self.soundManager.playSound(name: "click.wav")
 

Viewmodel

 class SoundManager: ObservableObject {
    var player: AVAudioPlayer?
    
    func playSound(name: String){
        let path = Bundle.main.path(forResource: name, ofType: nil)
        let url = URL(fileURLWithPath: path!)
        print("Play URL from name: (name)")
        do {
            player = try AVAudioPlayer(contentsOf: url)
            player?.play()
            print("Played sound")
        } catch {
            print("Error playing (name) sound")
        }
    }
}
 

Я этого не понимаю. Почему второй блок кода работает, а первый нет?

Комментарии:

1. Каков вывод операторов печати в обоих случаях?

2. Оба одинаковые. 1-я печать: воспроизведение URL-адреса из name: click.wav 2-я печать: воспроизводимый звук @ SHS

3. Насколько мне известно, во втором случае объект self.soundmanager является живым, вне action clouser. Таким образом, он может воспроизводить метод AVAudioPlayer (который является асинхронным). Но в первом случае объект SoundManager() завершает свой жизненный цикл, когда завершается действие clouser. Итак, функция .play() не (асинхронно) воспроизводит звук в первом случае.

Ответ №1:

Подумайте немного о том, что на самом деле делают два подхода. Во втором случае вы создаете объект SoundManager и присваиваете его переменной, которая является частью вашего объекта MultipleChoiceOption. Следовательно, оно будет работать до тех пор, пока объект MultipleChoiceOption активен. Затем вы используете этот SoundManager для воспроизведения звука.

В первом случае вы создаете другой объект SoundManager при нажатии кнопки, но никогда не присваиваете его переменной. То есть он будет работать до конца метода action, а затем будет немедленно завершен задолго до того, как ему удастся воспроизвести звук.