Мне очень просто нужно что-то запустить
- каждые 20 секунд
- просто, только когда приложение находится на переднем плане (явно не выполняется в фоновом режиме)
- очевидно, было бы более элегантно, если вам не нужно беспокоиться о том, что приложение входит и выходит из переднего плана.
- Проблема, я был поражен, узнав с помощью
scheduleRepeating
, что в симуляторе он продолжает работать, когда приложение находится в фоновом режиме: это не дает мне уверенности в том, что он явно не будет работать в фоновом режиме (некоторые? какие?) устройства - Проблема, я обнаружил, что на устройстве, тестируя как можно больше поколений/ОС,
scheduleRepeating
раздражает (в некоторых случаях?), запускается один раз, только когда приложение переходит в фоновый режим. То есть: он запускается "еще раз", как только приложение переходит на задний план. Соси.
Итак, чтобы повторить: в iOS, как иметь простой сервис, который запускается каждые 20 секунд и запускается только тогда, когда приложение находится на переднем плане, и это бесполезно. В идеале вам не нужно перезапускать это, проверить его или что-нибудь в течение жизни приложения...
действительно лучший способ сделать такую простую вещь?
Это мое (казалось бы) рабочее решение, которое неэлегантно. Разумеется, есть встроенный способ или что-то еще, чтобы сделать такую очевидную вещь в iOS?
open class SomeDaemon {
static let shared = SomeDaemon()
fileprivate init() { print("SomeDaemon is running") }
var timer: DispatchSourceTimer? = nil
let gap = 10 // seconds between runs
func launch() {
// you must call this from application#didLaunch
// harmless if you accidentally call more than once
// you DO NOT do ANYTHING on app pause/unpause/etc
if timer != nil {
print("SomeDaemon, timer running already")
return
}
timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)
timer?.scheduleRepeating(deadline: .now(), interval: .seconds(gap))
timer?.setEventHandler{ self. doSomeThing() }
timer?.resume()
}
private func doSomeThing() {
if UIApplication.shared.applicationState != .active {
print("avoided infuriating 'runs once more in bg' problem.")
return
}
// actually do your thing here
}
}