iKK
iKK

Reputation: 7012

Playing Audio in Background at a certain time

Using Swift5.2, Xcode11.4 and iOS13.4,

I try to run Audio at a certain time in the future.

Moreover, the App is in background mode (and the App is completely closed).

The Audiosession must be set up to keep the App responsive and the Audio sound shall start at delay-times up to 1 year.

I tried:

A) The Background Mode "Audio, AirPlay and Picture in Picture" is added:

enter image description here

B) The AudioSession and AVAudioPlayer is configured as follows:

import AVKit

var audioPlayer: AVAudioPlayer?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]?)
        -> Bool {

    do {
        //set up audio session
        let audioSession = AVAudioSession.sharedInstance()
        try audioSession.setCategory(.playback, mode: .default, options: [.defaultToSpeaker, .duckOthers])
        try audioSession.setActive(true)

        // Start AVAudioPlayer
        try audioPlayer = AVAudioPlayer(contentsOf: alertSound)
        audioPlayer!.numberOfLoops = -1 // play endlessly
        audioPlayer!.prepareToPlay()
        let currentAudioTime = audioPlayer!.deviceCurrentTime
        let delayTime: TimeInterval = 20.0 // here as an example, we use 20 seconds delay
        audioPlayer!.play(atTime: currentAudioTime + delayTime) // delayTime is the time after which the audio will start
    }
    catch {
      print(error)
    }

    return true
}

.

There are two problems with the code above:

  1. the session-Category .playback does cause the error Error Domain=NSOSStatusErrorDomain Code=-50 "(null)"

  2. the sound only plays when App is in foreground or in background-with-app-still-alive - but unfortunately not in background-with-app-completely-closed

Here my questions:

  1. Why is session-category .playback not working under iOS13.4 ?

  2. Why is the sound not playing when the app is completely closed ? (background-mode) ???

  3. Is it enough to just set the Background-mode tag "Audio, AirPlay and Picture in Picture" ? Or is there some code needed in order to fully implement background mode ? Is there something missing in code in order to make the sound future-start in a fully closed app ?

As for Question 1:

--> I've found a workaround and set the session-Category to .playAndRecored - after that the error goes away

try audioSession.setCategory(.playAndRecord, mode: .default, options: [.defaultToSpeaker, .duckOthers])

The question still remains: why is .playback not working ? And what is the difference between .playback and .playAndRecord ?

Upvotes: 3

Views: 1764

Answers (1)

Steve
Steve

Reputation: 106

  1. Why is session-category .playback not working under iOS13.4 ?

The .defaultToSpeaker option causes that error when used with .playback. I don't know why. If you remove it, it should work.

  1. Why is the sound not playing when the app is completely closed ? (background-mode) ???

The audio session is killed when the app is killed. If you want to play sounds beyond the lifetime of your app, you need to use remote notifications. See "Push notifications method" in this article on building an alarm clock app:

http://andrewmarinov.com/building-an-alarm-app-on-ios/

Note that there are limitations with this method, mainly that it requires the user to have an internet connection at the alarm time to work. This is the current way to setup an alarm beyond the lifetime of the app, other than sending a simple local notification which has its own limitations on sound playback and is silenced by the hardware silent switch.

There are other methods in that link to keep your app open, but it will notify the user (keeping the mic always on, or subscribing to frequent location updates).

  1. Is it enough to just set the Background-mode tag "Audio, AirPlay and Picture in Picture" ? Or is there some code needed in order to fully implement background mode ? Is there something missing in code in order to make the sound future-start in a fully closed app ?

This background mode keeps your app from being suspended while it has an active audio session. It does not prevent your app from being killed. Once killed, your app can't play any sound until it is opened again.

Upvotes: 1

Related Questions