J A S K I E R
J A S K I E R

Reputation: 2184

How to wait for the completion of the audio in SwiftUI?

All I want is to wait until the sound is finished and call the next sound...

This is main function in the ConentView struct I'm using to play the sounds with handlers:

func askNew(){

        self.isPlaying = true
        playQuestion{ 
        //1st audio
            askNew{
            //2nd audio to play

                //Change the global @State to see the result
                self.isPlaying = false
            }

        }

    }
}

Small functions to play the sounds. Obviously, they let us know only if the audio session starts, but does not await for the ending.

// MARK: - Question
func playQuestion(finished: () -> Void) {
   GSAudio.sharedInstance.playSound(sound: "question", type: "mp3", loop: false)
   finished()
}

func askNewSetCurrent(finished: () -> Void){
   GSAudio.sharedInstance.playSound(sound: "next_sound", type: "mp3", loop: false)
   finished()
}

Upvotes: 2

Views: 1549

Answers (1)

NyanNyan
NyanNyan

Reputation: 49

Try to think in this way

import AVFoundation

class SwiftUIViewModel: NSObject, ObservableObject {
    private var avPlayer: AVAudioPlayer!
    private var arrayOfAllTracks = [Track]()

    // call play track from view
    func playTrack() {
        self.play(track: arrayOfAllTracks[0])
    }

    private func play(track: Track) {
        self.avPlayer = try! AVAudioPlayer(contentsOf: track.url, fileTypeHint: AVFileType.mp3.rawValue)

        self.avPlayer?.delegate = self

        avPlayer.play()
    }

    private func playNext() {
        let track = self.arrayOfAllTracks[1]
        self.play(track: track)
    }
}

extension SwiftUIViewModel: AVAudioPlayerDelegate {
    func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
        guard flag else { return }

        self.playNext()
    }
}

struct Track {
    let url: URL!
}

Upvotes: 1

Related Questions