iOS Swift Timer не запускается, если приложение находится в фоновом режиме
Я занимаюсь разработкой библиотеки Cocoapod, в которой мне нужно вызывать функцию при срабатывании таймера. Я использую этот Cocoapod в приложении для iOS, таймер не срабатывает, когда приложение переходит в фоновое состояние
private var timer : DispatchSourceTimer? = nil
let queue = DispatchQueue(label: "sample.timer")
timer = DispatchSource.makeTimerSource(queue : queue)
timer?.setEventHandler
{
[weak self] in
self?.sendData()
}
timer?.scheduleRepeating(deadline: .now(), interval: .seconds(5))
3 ответа
Тот факт, что вы используете GCD таймер (альтернатива Timer
который может работать в фоновых потоках) заставляет задуматься, не смешиваете ли вы два совершенно разных использования слова "фон":
Одно значение "фон" связано с фоновыми очередями или потоками во время работы приложения. Это в отличие от "основного" потока / очереди.
И да, таймеры GCD отличаются от
Timer
экземпляры, поскольку они могут работать в фоновых очередях (при условии, что само приложение действительно работает).Другое значение "фон" связано с состоянием приложения. Вы можете либо работать на переднем плане, работать на заднем плане, либо быть приостановленным / прекращенным.
Во время работы приложения (на переднем или на заднем плане), таймеры (таймеры GCD или стандартные
Timer
) может работать. Но если приложение приостановлено или прекращено, все выполнение будет остановлено, включая таймеры.
Проблема в том, что вы пытаетесь запустить таймер, пока само приложение было приостановлено. Это не будет работать.
Ваше приложение не будет работать в фоновом режиме, если вы не:
попросить немного времени для выполнения некоторой задачи конечной длины (которая, IIRC, выполняется только в течение 3 минут); или же
В вашем приложении включен некоторый фоновый режим для определенных утвержденных целей (например, навигация, музыка, VOIP и т. д.).
Но приложения не могут продолжать работать в фоновом режиме (таймеры или что-то еще), за исключением тех особых узких ситуаций. Для получения дополнительной информации о фоновом выполнении см. Руководство по программированию приложения для iOS: Фоновое выполнение.
Попробуйте этот код, он работает нормально.
Timer.scheduledTimer(timeInterval: 5, target: self, selector: (#selector(self.callTimerFunction)), userInfo: nil, repeats: false)
func callTimerFunction() {
print("Hi.")
}
Это немного странно, но вы можете попытаться ограничить свое время в фоновом режиме и обойти эту проблему.
import AVFoundation
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, with: .mixWithOthers)
try AVAudioSession.sharedInstance().setActive(true)
}
catch { print(error) }