使用 RxSwift 定期调用 API

2024-01-04

我试图定期(每 10 秒)调用一个返回 model 的 Json 对象的 API:

struct MyModel { 
   var messagesCount: Int?
   var likesCount: Int?
}

并更新 UI 如果messageCount or likesCount值变化。 我尝试了 Timer 解决方案,但发现它有点混乱,我想要一个带有 RxSwift 和 RxAlamofire 的更干净的解决方案。

非常感谢任何帮助,因为我是 Rx 新手。


欢迎来到 StackOverflow!

为此需要相当多的操作员,我建议在ReactiveX 操作员页面 http://reactivex.io/documentation/operators.html,每次我忘记什么东西时我都会检查一下。

首先,确保MyModel符合Decodable因此它可以从 JSON 响应构建(请参阅Codable https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types).

let willEnterForegroundNotification = NotificationCenter.default.rx.notification(.UIApplicationWillEnterForeground)
let didEnterBackgroundNotification = NotificationCenter.default.rx.notification(.UIApplicationDidEnterBackground)

let myModelObservable = BehaviorRelay<MyModel?>(value: nil)

willEnterForegroundNotification
    // discard the notification object
    .map { _ in () }
    // emit an initial element to trigger the timer immediately upon subscription
    .startWith(())
    .flatMap { _ in 
        // create an interval timer which stops emitting when the app goes to the background
        return Observable<Int>.interval(10, scheduler: MainScheduler.instance)
            .takeUntil(didEnterBackgroundNotification)
    }
    .flatMapLatest { _ in 
        return RxAlamofire.requestData(.get, yourUrl)
            // get Data object from emitted tuple
            .map { $0.1 } 
            // ignore any network errors, otherwise the entire subscription is disposed
            .catchError { _ in .empty() } 
    } 
    // leverage Codable to turn Data into MyModel
    .map { try? JSONDecoder().decode(MyModel.self, from: $0) } }
    // operator from RxOptional to turn MyModel? into MyModel
    .filterNil() 
    .bind(to: myModelObservable)
    .disposed(by: disposeBag)

然后,您可以继续将数据流传输到 UI 元素中。

myModelObservable
    .map { $0.messagesCount }
    .map { "\($0) messages" }
    .bind(to: yourLabel.rx.text }
    .disposed(by: disposeBag)

我没有运行此代码,因此这里可能存在一些拼写错误/缺少转换,但这应该为您指明正确的方向。请随时要求澄清。如果是really对于 Rx 新手,我建议阅读入门指南 https://github.com/ReactiveX/RxSwift/blob/master/Documentation/GettingStarted.md。这很棒! Rx 非常强大,但我花了一段时间才掌握。

Edit

正如 @daniel-t 指出的,使用时不需要后台/前台簿记Observable<Int>.interval.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 RxSwift 定期调用 API 的相关文章

随机推荐