ios - 每 60 秒观察一次 observable,并与它在 RxSwift 中的先前值进行比较
问题描述
我想做的是:
- 每 60 秒观察
location
一次 observable 并比较距离是否超过了与大约 60 秒前发出的事件相比的阈值
发生的事情是$0
我总是得到第一个发出的事件,它不是每 60 秒更新一次。$1 有最新的发射事件。
这是代码:
Observable<Int>.timer(.seconds(0), period: .seconds(60), scheduler: MainScheduler.instance)
.withLatestFrom(location)
.distinctUntilChanged { $0.distance(from: $1).magnitude < 10.0 }
.subscribe(onNext: { (location) in
print(location)
})
.disposed(by: disposeBag)
解决方案
您要求的是在设备超过一定速度时发出一个值,该值实际上是在位置对象中提供的。就用它吧。
extension CLLocationManager {
func goingFast(threshold: CLLocationSpeed) -> Observable<CLLocation> {
return rx.didUpdateLocations
.compactMap { $0.last }
.filter { $0.speed > threshold }
}
}
有了上述内容,如果您想知道设备在过去 60 秒内的任何时间点是否超过 10 m/s,您可以使用sample
Alexander 在评论中提到的:
let manager = CLLocationManager()
let fast = manager.goingFast(threshold: 0.167)
.sample(Observable<Int>.interval(.seconds(60), scheduler: MainScheduler.instance))
也就是说,作为跟踪幅度增加的一般情况,您需要使用scan
运算符。
extension CLLocationManager {
func example(period: RxTimeInterval, threshold: Double, scheduler: SchedulerType) -> Observable<CLLocation> {
return rx.didUpdateLocations
.compactMap { $0.last }
.sample(Observable<Int>.interval(period, scheduler: scheduler))
.scan((CLLocation?.none, false)) { last, current in
if (last.0?.distance(from: current).magnitude ?? 0) < threshold {
return (current, false)
}
else {
return (current, true)
}
}
.filter { $0.1 }
.compactMap { $0.0 }
}
}
推荐阅读
- javascript - 有没有办法用javascript清除页面?
- python - @property 和 @value.setter 的用法
- python-3.x - Selenium 只是弹出一个空白窗口(它不加载网页),怎么会?
- android - 小部件问题:BroadcastQueue:不允许后台执行:接收 Intent
- elasticsearch - 动态场弹性搜索的问题
- javascript - 在 Array.prototype.map 中退一步迭代
- android - 在 Kotlin 中固定 List 大小的最佳方法是什么
- java - Spring - 在@Autowired 上使用@Resource 以获得更好的性能
- javascript - 使用 onkeypress 事件验证利率
- prometheus - 数据可以存储在本地和远程存储中吗