Search code examples
swiftavaudioplayer

How to run background timer with app closed playing audio samples in Swift


I am making a drum machine app, which requires playing back short samples in a sequence. I would like to continue the sequence playing with the app closed.

I've followed the standard process for enabling background audio and data processing capabilities, but I need a suitable timer with at least second granularity that will trigger in the background.

What timer can I use with the app closed?

Here's some example code I want to continue playing:

UPDATED WITH SOLUTION

class ViewController: UIViewController {

    var player: AVAudioPlayer? = nil
    var silence: AVAudioPlayer? = nil // SOLUTION

    override func viewDidLoad() {
        super.viewDidLoad()

        let bass = Bundle.main.bundlePath + "/bd.mp3"
        let backing = Bundle.main.bundlePath + "/silence.mp3" // SOLUTION

        do {
            try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: []) // SOLUTION
            try AVAudioSession.sharedInstance().setActive(true) // SOLUTION

            player = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: bass))
            silence = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: backing)) // SOLUTION
        } catch {
            print(error)
        }

        Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(beat), userInfo: nil, repeats: true)

        silence?.numberOfLoops = -1 // Infinite // SOLUTION
        silence?.play() // SOLUTION
    }

    @objc func beat() {
        player?.play()
    }

}

Solution

  • The solution I found is to play a silent track on loop, which allows the timer to run in the background. My app then needs to stop the silent track to go into the background normally.