Наблюдайте наблюдаемую каждые 60 секунд и сравните с ее предыдущим значением в RxSwift - PullRequest
0 голосов
/ 07 апреля 2020

Я хочу сделать следующее:

  • Наблюдать location, наблюдаемый каждые 60 секунд, и сравнить, прошло ли расстояние пороговое значение, по сравнению с событием, которое было излучено ~ 60 секунд * 1013. *

То, что происходит в $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)

1 Ответ

1 голос
/ 07 апреля 2020

То, что вы запрашиваете, это испускание значения, когда устройство движется с определенной скоростью, которая является значением, которое фактически предоставляется в объекте местоположения. Просто используйте его.

extension CLLocationManager {
    func goingFast(threshold: CLLocationSpeed) -> Observable<CLLocation> {
        return rx.didUpdateLocations
            .compactMap { $0.last }
            .filter { $0.speed > threshold }
    }
}

С учетом вышеизложенного, если вы хотите узнать, превысило ли устройство скорость 10 м / с в любой момент за последние 60 секунд, вы должны использовать sample, как указано в Александр в комментариях:

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 }
    }
}
...