我只是想要一个简单的东西在iOS上运行
- 每20秒运行一次
- 只在应用程序处于前台时运行(明确地说,不在后台运行)
- 显然,如果您不必跟踪应用程序进出前台,那将更加优雅
- 问题在于,我惊讶地发现,在模拟器中使用
scheduleRepeating
时,当应用程序在后台时它会继续运行:这让我不太确信它在某些设备上明确地不会在后台运行 - 我发现,在设备上测试尽可能多的OS版本和代数时,
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
}
}
DispatchSourceTimer
已经更加整洁了。 - Fattie