Fat*_*tie 13 service ios swift3
我只是想要运行一些东西
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
}
}
Run Code Online (Sandbox Code Playgroud)
它并不华丽,但效果非常好。
struct ForegroundTimer {
static var sharedTimerDelegate: ForegroundTimerDelegate?
static var sharedTimer = Timer()
private var timeInterval: Double = 20.0
static func startTimer() {
ForegroundTimer.waitingTimer.invalidate()
var wait = 0.0
if let time = ForegroundTimer.startedTime {
wait = timeInterval - (Date().timeIntervalSince1970 - time).truncatingRemainder(dividingBy: Int(timeInterval))
} else {
ForegroundTimer.startedTime = Date().timeIntervalSince1970
}
waitingTimer = Timer.scheduledTimer(withTimeInterval: wait, repeats: false) { (timer) in
ForegroundTimer.sharedTimerDelegate?.timeDidPass()
ForegroundTimer.sharedTimer = Timer.scheduledTimer(withTimeInterval: timeInterval, repeats: true, block: { (timer) in
ForegroundTimer.sharedTimerDelegate?.timeDidPass()
})
}
}
static func pauseTimer() {
ForegroundTimer.sharedTimer.invalidate()
}
private static var startedTime: TimeInterval?
private static var waitingTimer = Timer()
}
protocol ForegroundTimerDelegate {
func timeDidPass()
}
Run Code Online (Sandbox Code Playgroud)
上面的代码可以按原样使用。当然,您可以timeInterval选择任何您想要的时间间隔。
在 AppDelegate.swift 中,有以下两个方法:
func applicationDidBecomeActive(_ application: UIApplication) {
ForegroundTimer.startTimer()
}
func applicationDidEnterBackground(_ application: UIApplication) {
ForegroundTimer.pauseTimer()
}
Run Code Online (Sandbox Code Playgroud)
然后,让您想要“监听”计时器的任何类实现ForegroundTimerDelegate它所需的方法timeDidPass()。最后,将该 class/ 分配self给ForegroundTimer.sharedTimerDelegate. 例如:
class ViewController: UIViewController, ForegroundTimerDelegate {
func viewDidLoad() {
ForegroundTimer.sharedTimerDelegate = self
}
func timeDidPass() {
print("20 in-foreground seconds passed")
}
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
626 次 |
| 最近记录: |