ios - 使用 RxSwift 定期调用 API

标签 ios swift rx-swift rxalamofire

我正在尝试定期(每 10 秒)调用一个返回模型的 Json 对象的 API:

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

如果 messageCountlikesCount 值发生变化,则更新 UI。 我尝试了 Timer 解决方案,但我发现它有点乱,我想要一个使用 RxSwift 和 RxAlamofire 的更干净的解决方案。

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

最佳答案

欢迎使用 StackOverflow!

为此需要很多运算符,我建议在 ReactiveX Operator page 上查找它们,每当我忘记某事时,我都会检查一下。

首先,确保MyModel符合 Decodable因此它可以从 JSON 响应构建(参见 Codable )。

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)

我没有运行此代码,因此此处可能存在一些拼写错误/缺少转换,但这应该为您指明了正确的方向。随时要求澄清。如果真的是 Rx 的新手,我建议阅读 Getting Started guide .这很棒! Rx 非常强大,但我花了一段时间才掌握。

编辑

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

关于ios - 使用 RxSwift 定期调用 API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52311965/

相关文章:

ios - 使用 scrollView 和 imageView 的 bounds.height 属性计算 zoomScaleForHeight

swift - iOS RxSwift - 如何解包 `Optional<Optional<T>>` 或 `T??`?

ios - RxDataSources 单元重新加载动画无法正常工作

ios - UIImageView 忽略 contentMode 的变化

ios - native 链接失败,重复符号 : '_main' while adding native Binding Dll and Xamarin. Firebase.iOS.Database

swift - 快速连接到随机 Storyboard的按钮(Xcode 版本 8.2.1

ios - iOS RxSwift-如何使用Amb运算符?

ios - 是否可以使用自动化 UI 测试通过 Instruments 运行 Network Link Conditioner?

iphone - 对多个Facebook request_ids执行操作

ios - iOS Swift 中简单的低延迟音频播放