1

I'm working with the AudioKit framework and looking to use DispatchGroup to make a method work async. I'd like for the player.load method to run only after the audioFile has been created; right now it's throwing an error ~50% of the time and I suspect it's due to timing. I've used DispatchGroup with success in other circumstances, but never in a do/try/catch. Is there a way to make this part of the function work with it? If not, is there a way to set up a closure? Thanks!

func createPlayer(fileName: String) -> AKPlayer {
    let player = AKPlayer()
    let audioFile : AKAudioFile
    player.mixer >>> mixer
    do {
        try audioFile = AKAudioFile(readFileName: "\(fileName).mp3")
        player.load(audioFile: audioFile)
        print("AudioFile \(fileName), \(audioFile) loaded")
    } catch { print("No audio file read, looking for \(fileName).mp3")
    }
    player.isLooping = false
    player.fade.inTime = 2 // in seconds
    player.fade.outTime = 2
    player.stopEnvelopeTime = 2
    player.completionHandler = {
        print("Completion")
        self.player.detach()
    }
    player.play()
    return player
}
moosgrn
  • 379
  • 3
  • 13
  • "Due to timing" what this this mean, precisely? is there some broader context that would be useful to know about here? – Alexander Oct 03 '19 at 01:50
  • The player is attempting to load the audioFile before the audioFile has the .mp3 attached to it, and will then catch. – moosgrn Oct 03 '19 at 01:54
  • Oh I see. Looks like you need to keep the "asyncness" going. You have a few tools available to you here. IDK what you do precisely with this `createPlayer(fileName:)` method, but it's probably best to make it async, and not return `AKPlayer`. You have a few tools available to you. You can use something like RxSwift or Apple's Combine and return a `Observable`, `PormiseKit` to return a `Promise` or (the worst option) add a callback that takes a `Result` as a parameter. – Alexander Oct 03 '19 at 02:05
  • @Alexander thanks for the response! Would you be able to give me an example of how the callback would work in this scenario? The other options your provided look great, however they are directions I've only heard of and look forward to learning about in the future. – moosgrn Oct 03 '19 at 02:27
  • 1
    You would wrap your entire method body in a closure passed to `someDispatchQueue.async`, and have the last line of that closure call the call back. See the many answers on https://stackoverflow.com/q/25203556/3141234 – Alexander Oct 03 '19 at 02:55
  • Very helpful; thanks! – moosgrn Oct 03 '19 at 02:56

0 Answers0