How to create an iOS alarm clock that runs in the background properly
Asked Answered
H

1

10

I would like to insert an alarm clock function in an iOS app I am developing, and as a reference, I installed a popular App called "Alarmy."

I managed to keep my app running in the background, just using AVAudioSession properties; however, I noticed that the app consumes a lot of battery during the phone sleep.

After some testing, I think this is due to the app activating the speakers (and keeping them ON) immediately after the AVAudioSession activation.

Even if there is no actual sound playing until the audioPlayer.play(atTime: audioPlayer.deviceCurrentTime + Double(seconds)) is triggered, if I get very very close to my iPhone 7 speakers, I can hear the little buzzing sound that indicates that the speakers are ON. This implicates that the speakers are playing an "empty sound" de facto.

This buzzing sound does not exist when I set the alarm with Alarmy; it just starts playing when it is supposed to.

I did not find any other way to maintain my app in the background and play an alarm sound at a specified time. There are Local Notifications, of course, but they do not allow to play a sound when the phone is silenced.

Going back to "Alarmy," I've seen that they are not only able to play a background alarm without any need to activate the speakers first, but they are also able to put the volume at the max level in the background. Are they maybe triggering some other iOS background mode to achieve those, perhaps using Background Fetch or Processing in some clever way? Is there any known way to replicate those behaviors?

Thanks in advance!

Here is the current code I use to set the alarm:

private func setNewAlarm(audioPlayer: AVAudioPlayer, seconds: Int, ringtone: String) {

        do {

            self.setNotificationAlarm(audioPlayer: audioPlayer, seconds: seconds, ringtone: ringtone, result: result) 
            //This calls the method I use to set a secondary alarm using local notifications, just in case the user closes the app

            try AVAudioSession.sharedInstance().setActive(false)
            try AVAudioSession.sharedInstance().setCategory(.playback, options: [ .mixWithOthers])
            try AVAudioSession.sharedInstance().setActive(true)

        } catch let error as NSError {
            print("AVAudioSession error: \(error.localizedDescription)")
        }

        audioPlayer.prepareToPlay()

        audioPlayer.play(atTime: audioPlayer.deviceCurrentTime + Double(seconds))

        result(true)

    }
Hardie answered 12/1, 2020 at 23:13 Comment(3)
Please see: #41492716Diffractometer
Have any luck with finding a better answer?Raeannraeburn
Activating a live activity appears to affect the duration an app runs in the background before it is stopped, but it seems inconsistentCoppage
G
-1

Set AVAudioPlayer volume to 0 and you wont hear the white noise sound

Gallic answered 12/8 at 17:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.