Hello,
I have been working on an audio module that plays a specific sound at regular intervals -- similar to a workout timer that alerts the user to switching exercises every few minutes.
I'm configuring my audio session like this:
let session = AVAudioSession.sharedlnstance()
try session.setCategory(
.playback,
mode: default,
options: [.interruptSpokenAudioAndMixWithOthers, duckOthers]
)
self.engine.attach(self.player)
self.engine.connect(self.player, to: self.engine.outputNode, format: self.audioFormat)
try session. setActive(true)
I schedule playback using a DispatchQueue (that's what scheduleAudio does):
self.scheduleAudio(at: interval.start) {
do {
try audio.engine.start()
audio.node.play()
for kue in interval.cues {
audio.node.scheduleBuffer(kue.buffer, at: AVAudioTime(hostTime: kue.hostTime))
}
} catch {
print (Audio activation failed: \(error)")
}
}
This works perfectly in the foreground. But once the app goes into the background, the scheduled callback runs, yet the audio engine does not start, resulting in 'AVAudioSession.ErrorCode.cannotStartPlaying'.
Interestingly, if the app is already playing audio before going to the background, the scheduled sounds continue to play as expected.
I have added the required background audio mode to my Info plist file by including the key UlBackgroundModes with the value audio.
Is there anything else I should configure? What is the best practice to play periodic audio cues when the app runs in the background?
How do apps that do turn-by-turn navigation handle continuous audio playback in the background?
Any advice or pointers would be greatly appreciated!