📂
RxSwift
  • RxSwift 中文文档
  • 1. 为什么要使用 RxSwift?
  • 2. 你好 RxSwift!
  • 3. 函数响应式编程
    • 3.1 函数式编程
    • 3.2 函数式编程 -> 函数响应式编程
    • 3.3 数据绑定
  • 4. RxSwift 核心
    • 4.1 Observable - 可监听序列
      • Single
      • Completable
      • Maybe
      • Driver
      • Signal
      • ControlEvent
    • 4.2 Observer - 观察者
      • AnyObserver
      • Binder
    • 4.3 Observable & Observer 既是可监听序列也是观察者
      • AsyncSubject
      • PublishSubject
      • ReplaySubject
      • BehaviorSubject
      • Variable(已弃用)
      • ControlProperty
    • 4.4 Operator - 操作符
    • 4.5 Disposable - 可被清除的资源
    • 4.6 Schedulers - 调度器
    • 4.7 Error Handling - 错误处理
  • 5. 如何选择操作符?
    • amb
    • buffer
    • catchError
    • combineLatest
    • concat
    • concatMap
    • connect
    • create
    • debounce
    • debug
    • deferred
    • delay
    • delaySubscription
    • dematerialize
    • distinctUntilChanged
    • do
    • elementAt
    • empty
    • error
    • filter
    • flatMap
    • flatMapLatest
    • from
    • groupBy
    • ignoreElements
    • interval
    • just
    • map
    • merge
    • materialize
    • never
    • observeOn
    • publish
    • reduce
    • refCount
    • repeatElement
    • replay
    • retry
    • sample
    • scan
    • shareReplay
    • single
    • skip
    • skipUntil
    • skipWhile
    • startWith
    • subscribeOn
    • take
    • takeLast
    • takeUntil
    • takeWhile
    • timeout
    • timer
    • using
    • window
    • withLatestFrom
    • zip
  • 6. 更多示例
    • ImagePicker - 图片选择器
    • TableViewSectionedViewController - 多层级的列表页
    • Calculator - 计算器
  • 7. RxSwift 常用架构
    • 7.1 MVVM
      • Github Signup(示例)
    • 7.2 RxFeedback
      • Github Search(示例)
    • 7.3 ReactorKit
      • Github Search(示例)
  • 8. RxSwift 生态系统
  • 9. 学习资源
  • 10. 关于本文档
    • 10.1 文档更新日志
  • 食谱
    • RxSwift 5 更新了什么?
    • RxRelay
    • 纯函数
    • 附加作用
    • 共享附加作用
Powered by GitBook
On this page
  • RxSwift 生态系统
  • ReactiveX 生态系统
  • Android
  • Web 前端
  • 总结

Was this helpful?

8. RxSwift 生态系统

PreviousGithub Search(示例)Next9. 学习资源

Last updated 4 years ago

Was this helpful?

RxSwift 生态系统

RxCocoa 给 UI框架 提供了 支持,让我们能够使用按钮点击序列,输入框当前文本序列等。不过 RxCocoa 也只是 RxSwift 生态系统 中的一员。RxSwift 生态系统还给其他框架提供了 支持:

  • - UITableView 和 UICollectionView 数据源

  • - 页面手势

  • - 地图

  • - 陀螺仪

  • - 网络请求

  • - CoreData 数据库

  • - Realm 数据库

  • - 图片选择器

  • - 行为

  • - WebView

  • - 全局通知

  • - 添加一些有用的操作符

  • ...

你只需要几行代码就可以布局一个多 Section 的 tabelView:

let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String, Int>>()
Observable.just([SectionModel(model: "title", items: [1, 2, 3])])
    .bind(to: tableView.rx.items(dataSource: dataSource))
    .disposed(by: disposeBag)
let stringURL = ""

// 使用 NSURLSession
let session = NSURLSession.sharedSession()

_ = session.rx
        .json(.get, stringURL)
        .observeOn(MainScheduler.instance)
        .subscribe { print($0) }

// 使用 Alamofire 引擎

_ = json(.get, stringURL)
    .observeOn(MainScheduler.instance)
    .subscribe { print($0) }

// 使用 Alamofire manager

let manager = Manager.sharedInstance

_ = manager.rx.json(.get, stringURL)
    .observeOn(MainScheduler.instance)
    .subscribe { print($0) }

// URLHTTPResponse + Validation + String
_ = manager.rx.request(.get, stringURL)
    .flatMap {
        $0
            .validate(statusCode: 200 ..< 300)
            .validate(contentType: ["text/json"])
            .rx.string()
    }
    .observeOn(MainScheduler.instance)
    .subscribe { print($0) }

监听数据:

let realm = try! Realm()
let laps = realm.objects(Lap.self)

Observable.collection(from: laps)
  .map {
    laps in "\(laps.count) laps"
  }
  .subscribe(onNext: { text  in
    print(text)
  })

添加数据:

let realm = try! Realm()
let messages = [Message("hello"), Message("world")]

Observable.from(messages)
  .subscribe(realm.rx.add())

删除数据:

let realm = try! Realm()
let messages = realm.objects(Message.self)

Observable.from(messages)
  .subscribe(realm.rx.delete())

Android

iOS(RxSwift) 版:

...
let usernameValid = usernameOutlet.rx.text.orEmpty
    .map { $0.characters.count >= minimalUsernameLength }
    .share(replay: 1)

let passwordValid = passwordOutlet.rx.text.orEmpty
    .map { $0.characters.count >= minimalPasswordLength }
    .share(replay: 1)

let everythingValid = Observable
    .combineLatest(usernameValid, passwordValid) { $0 && $1 }
    .share(replay: 1)

usernameValid
    .bind(to: passwordOutlet.rx.isEnabled)
    .disposed(by: disposeBag)

usernameValid
    .bind(to: usernameValidOutlet.rx.isHidden)
    .disposed(by: disposeBag)

passwordValid
    .bind(to: passwordValidOutlet.rx.isHidden)
    .disposed(by: disposeBag)

everythingValid
    .bind(to: doSomethingOutlet.rx.isEnabled)
    .disposed(by: disposeBag)
...

Android(RxJava) 版:

...
final Observable<Boolean> usernameValid = RxTextView.textChanges(usernameEditText)
        .map(text -> text.length() >= minimalUsernameLength)
        .compose(Rx.shareReplay(1));

final Observable<Boolean> passwordValid = RxTextView.textChanges(usernameEditText)
        .map(text -> text.length() >= minimalPasswordLength)
        .compose(Rx.shareReplay(1));

final Observable<Boolean> everythingValid = Observable
        .combineLatest(usernameValid, passwordValid, (isUsernameValid, isPasswordValid) -> isUsernameValid && isPasswordValid)
        .compose(Rx.shareReplay(1));

disposables.add(usernameValid
        .subscribe(RxView.enabled(passwordEditText)));

disposables.add(usernameValid
        .subscribe(RxView.visibility(usernameValidTextView)));

disposables.add(passwordValid
        .subscribe(RxView.visibility(passwordValidTextView)));

disposables.add(everythingValid
        .subscribe(RxView.enabled(doSomethingButton)));
...

这两段代码的逻辑是一样的,一个是 iOS(RxSwift) 版本,另一个是 Android(RxJava) 版本。仔细对比以后,你会发现它们的书写方式都是差不多的。

这样一来,你就可以用同一套逻辑来写跨平台应用,而且这个应用是纯原生的。这不仅节省了开发时间,而且还提升了 App 的质量。

Web 前端

var $input = $('#input'),
    $results = $('#results');

Rx.Observable.fromEvent($input, 'keyup')
    .map(e => e.target.value)
    .filter(text => text.length > 2)
    .throttle(500 /* ms */);
    .distinctUntilChanged();
    .flatMapLatest(searchWikipedia);
    .subscribe(data => {
        var res = data[1];
        $results.empty();
        $.each(res, (_, value) => $('<li>' + value + '</li>').appendTo($results));
    }, error => {
        $results.empty();
        $('<li>Error: ' + error + '</li>').appendTo($results);
    });

当用户输入一个稳定的关键字后,向维基百科请求搜索结果,然后显示出来。

总结

书写 tabelView 或 collectionView 的数据源是一件非常繁琐的事情,有一大堆的代理方法需要被执行。 可以帮助你简化这一过程。你可以用它来布局多层级的列表页,并且它还可以提供动画支持。

你可以点击 来了解更多信息。

是一个非常流行的网络请求框架。 是用 封装的 。它使得网络请求调用变得更加平滑,处理请求结果变得更简洁,更高效:

你可以点击 来了解更多信息。

是一个十分前卫的跨平台数据库,他想要替换 Core Data 和 SQLite。 是用 封装的 。它使我们可以用 Rx 的方式监听数据变化,或者将数据写入数据库。

你可以点击 来了解更多信息。

ReactiveX 生态系统

我们之前提到过 是 的 Swift 版本。而 (简写: Rx)是一个跨平台框架。它不仅可以用来写 iOS ,你还可以用它来写 Android,Web 前端和后台。并且每个平台都和 RxSwift 一样有一套 生态系统。 支持多种编程语言,如:Swift,Java,JS,C#,Scala,Kotlin,Go 等。只要你掌握了其中一门语言,你很容易就能够熟悉其他的语言。

是 Android 平台上非常流行的响应式编程框架,它也是 的 Java 版本。

我们还是用来做演示:

是 Web 前端 平台上非常流行的响应式编程框架,它也是 的 JS 版本。而且主流的前端框架都提供了 支持,如:,,,等。

下面这个例子是用 写的,它和 GitHub 搜索 十分相似,只不过他搜索的是维基百科:

即便你没有学过 Web 前端开发,但是只要你熟悉 ,以上代码你也能够看懂。

由于 支持多种后台语言,如:Java,JS,Go。所以你也可以用它来写后台。

如果你已经能够熟练使用 ,那么你就已经具有某种“天赋”,这种“天赋”可以帮助你快速上手其他平台。你只需要学习一些和平台相关的知识,就可以写出交互相当复杂的应用程序。因为你的 技巧是可以跨平台复用的。

另外,你的学习效率也会更高,如果你在 中学到了某些技巧,那么这个技巧通常也可以被应用到 Android 或者其他的平台。如果你在 中学到了某些技巧,那么这个技巧通常也可以被应用到 iOS 平台。因此,你的学习资源也就不再局限于 ,你还可以浏览其他平台上关于 的教程。

下一章将提供一些关于 。

RxDataSources
RxDataSources
RxAlamofire
Alamofire
RxAlamofire
RxSwift
Alamofire
RxAlamofire
RxRealm
Realm
RxRealm
RxSwift
Realm
RxRealm
RxSwift
Rx
ReactiveX
Rx
Rx
RxJava
Rx
输入验证
RxJS
Rx
Rx
jQuery
RxJS-DOM
AngularJS
RxEmber
RxJS
Rx
Rx
RxSwift
Rx
RxSwift
RxJava
RxSwift
Rx
RxSwift 的学习资源
Rx
Rx
RxDataSources
RxGesture
RxMKMapView
RxCoreMotion
RxAlamofire
RxCoreData
RxRealm
RxMediaPicker
Action
RxWebKit
RxEventHub
RxSwiftExt
RxDataSources