Как создать iOS будильник, который работает в фоновом режиме правильно - PullRequest
4 голосов
/ 13 января 2020

Я хотел бы добавить функцию будильника в приложение iOS, которое я разрабатываю, и в качестве справочного материала я установил популярное приложение под названием "Alarmy".

I удалось сохранить приложение в фоновом режиме, просто используя свойства AVAudioSession; Тем не менее, я заметил, что приложение потребляет много батареи во время сна телефона.

После некоторого тестирования, я думаю, это связано с тем, что приложение активирует динамики (и держит их включенными) сразу после активации AVAudioSession.

Даже если звук не воспроизводится до тех пор, пока не будет запущен audioPlayer.play (atTime: audioPlayer.deviceCurrentTime + Double (секунд)) , если я очень близко подхожу к своему iPhone 7 динамиков, я слышу небольшой гудящий звук, который указывает на то, что динамики включены. Это подразумевает, что колонки де-факто воспроизводят «пустой звук».

Этот гудящий звук не существует, когда я установил будильник с помощью Alarmy; он просто начинает играть, когда должен.

Я не нашел другого способа сохранить приложение в фоновом режиме и воспроизводить сигнал будильника в указанное время. Конечно, есть локальные уведомления, но они не позволяют воспроизводить звук, когда телефон выключен.

Возвращаясь к «Alarmy», я видел, что они не только могут воспроизводить фоновый сигнал без необходимости сначала активировать громкоговорители, но также способны устанавливать максимальный уровень громкости. на заднем фоне. Возможно, они запускают какой-то другой iOS фоновый режим для достижения этого, возможно, используя Background Fetch или Processing каким-то умным способом? Есть ли какой-либо известный способ повторить это поведение?

Заранее спасибо!

Вот текущий код, который я использую для установки будильника:

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)

    }
...