[英]Observable.interval not working in background state
我正在嘗試使用 RxSwift 創建一個簡單的計時器,我的靈感來自這個答案 ()。 當應用程序在前台時它工作正常。 問題是,如果應用程序 state 進入后台,如果應用程序 state 再次處於前台,它將停止然后從其停留的位置開始計數。
https://stackoverflow.com/a/41198811/3950721
快速瀏覽; 帶有 RxSwift 的簡單計時器
您正在經歷的是標准和預期的行為。 當應用程序進入后台時,所有計時器和其他后台任務(無論是否在 Rx 中)都會停止。
為了讓任何人幫助您,您需要解釋您正在嘗試做什么,以便我們可以想出另一種方法來做到這一點。
例如,在我的一個應用程序中,用戶應該在 5 分鍾不活動后退出,所以我有這個來確保它發生:
let idleTime = 5 * 60
let foregroundTimerTripped = Observable.merge(
application.rx.methodInvoked(#selector(UIApplication.sendEvent(_:))).map(to: ()),
rx.methodInvoked(#selector(UIApplicationDelegate.applicationWillEnterForeground(_:))).map(to: ())
)
.debounce(.seconds(idleTime), scheduler: MainScheduler.instance)
let backgroundTime = rx.methodInvoked(#selector(UIApplicationDelegate.applicationDidEnterBackground(_:)))
.map(to: ())
.flatMap { Observable.just(Date()) }
let foregroundTime = rx.methodInvoked(#selector(UIApplicationDelegate.applicationWillEnterForeground(_:)))
.map(to: ())
.flatMap { Observable.just(Date()) }
let backgroundTimerTripped = foregroundTime
.withLatestFrom(backgroundTime) { $0.timeIntervalSince($1) }
.filter { $0 > TimeInterval(idleTime) }
.withLatestFrom(bearer)
let timeToLogout = Observable.merge(foregroundTimerTripped, backgroundTimerTripped)
除了丹尼爾的回答,如果你和我有類似的問題(像一次性密碼屏幕一樣過期的計時器),這是我的解決方案;
由於到期日期,只要計時器運行,它就會發出剩余的秒數到到期日期。 由於過期日期是恆定的,剩余秒數不受應用程序 state 的影響。
let expireDate = Date().addingTimeInterval(TimeInterval(seconds))
timerBag = DisposeBag() // to release timer.
Observable<Int>
.interval(.seconds(1), scheduler: MainScheduler.instance)
.map { _ in expireDate }
.compactMap( expireDate -> Int? in
let calendar = Calendar.current
let components = calendar.dateComponents([.second], from: Date(), to: expireDate)
return components.second
}
.subscribe(onNext: { [weak self] remainingSecondsToExpire in
print(remainingSecondsToExpire)
}).disposed(by: timerBag!)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.