要求
- Xcode 9.0+
- Swift 4.0+
- iOS 9.0+
目录
- 介绍
- 使用
- 示例
介绍
简单来说,Rx是一个基于各大编程语言通过扩展源语言的方法,封装简化了的基于响应链的函数式异步编程框架,目前有RxJava、RxJS等,而RxSwift就是基于Swift语言进行的扩展库。
《RxSwift中文文档》
一般来说,如果你对比使用过Objective-C和Swift语言,你会发现Swift确实很简洁高效,代码量比使用OC要少2/3以上,而RxSwift
是对Swift的一些基本数据类型和操作方法进一步进行了扩展和简化,进一步减少了代码量。
RxCocoa
则是对UIKit中的控件的使用进行了扩展和简化,是我们最常用的模块。
使用
- Swift 4.0(最新)
- Swift 3.x (使用
rxswift-3.0
分支) - Swift 2.3 (使用
rxswift-2.0
分支)
CocoaPods
# Podfile
use_frameworks!
target 'YOUR_TARGET_NAME' do
pod 'RxSwift', '~> 4.0'
pod 'RxCocoa', '~> 4.0'
end
# RxTest and RxBlocking make the most sense in the context of unit/integration tests
target 'YOUR_TESTING_TARGET' do
pod 'RxBlocking', '~> 4.0'
pod 'RxTest', '~> 4.0'
end
然后执行$ pod install
Carthage
- 在Cartfile中加入
github "ReactiveX/RxSwift" ~> 4.0
- 然后执行
carthage update --platform iOS
SwiftPackageManager
- Package.swift
import PackageDescription
let package = Package(
name: "RxTestProject",
dependencies: [
.package(url: "https://github.com/ReactiveX/RxSwift.git", "4.0.0" ..< "5.0.0")
],
targets: [
.target(name: "RxTestProject", dependencies: ["RxSwift", "RxCocoa"])
]
)
- 执行
swift build
手动集成
-
下载RxSwift源码,然后将
Rx.xcodeproj
拖到你的工程中
-
添加
RxSwift.framework
和RxCocoa.framework
库到你的工程中
import RxSwift
和import RxCocoa
即可
示例
详细的用法请参照官方文档,本文简单从一个UITableView的RxSwift实现,来介绍RxSwift的简单用法
传统的Swift实现方式
- 新建一个基于UITableViewController的VC:
import UIKit
class ViewController: UITableViewController {}
- 创建ViewModel:
struct Song {
let name: String
let singer: String
init(name: String, singer: String) {
self.name = name
self.singer = singer
}
}
extension Song: CustomStringConvertible{
var description: String{
return "name: \(name), singer: \(singer)"
}
}
struct SongViewModel {
let data: [Song] = [
.init(name: "Name1", singer: "Singer1"),
.init(name: "Name2", singer: "Singer2"),
.init(name: "Name3", singer: "Singer3")
]
}
- 指定tableView的dataSource,实现DataSource和Delegate方法,配置Cell:
lazy var songViewModel = SongViewModel()
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return songViewModel.data.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let song = songViewModel.data[indexPath.row]
cell.textLabel?.text = song.name
cell.detailTextLabel?.text = song.singer
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print(songViewModel.data[indexPath.row])
}
传统方式下,实现以上功能的代码行数为55行
RxSwift实现方式
- 新建一个基于UITableViewController的VC:
import UIKit
import RxCocoa
class RxViewController: UITableViewController {}
- 创建ViewModel:
import RxSwift
struct RxSongListViewModel {
let data = Observable.of([
Song(name: "Name1", singer: "Singer1"),
Song(name: "Name2", singer: "Singer2"),
Song(name: "Name3", singer: "Singer3")
])
}
- Rx数据和UI绑定:
lazy var viewModel = RxSongListViewModel()
lazy var disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = nil
tableView.dataSource = nil
viewModel.data.bind(to: tableView.rx.items(cellIdentifier: "Cell")){
_, song, cell in
cell.textLabel?.text = song.name
cell.detailTextLabel?.text = song.singer
}.disposed(by: disposeBag)
tableView.rx.itemSelected.subscribe(onNext: {
indexPath in
print(indexPath)
}).disposed(by: disposeBag)
}
上述实现方式下,代码行数为40,可见比传统方式更加简洁
- 值得注意的是如果一个VC是基于
UITableViewController
,那么初始化的时候,tableView.delegate
和tableView.dataSource
默认是self
,这与RxCocoa
中的设置会冲突导致奔溃:
这段assert内容的大概意思是,如果你正在使用RxCocoa来将数据和UI绑定的话,你要确保tableView的delegate和dataSource为nil
解决办法:
override func viewDidLoad() {
super.viewDidLoad()
// 手动设置为nil
tableView.delegate = nil
tableView.dataSource = nil
}
至于Rx的原理,这里不作详细解释,只指出RxSwift是基于Observable这么一个类的对象将普通数据封装为Rx可观察对象,然后将这个数据类对象异步绑定
bind(to: )
给RxCocoa的UI对象,来达到动态数据设置的目的。
如果对你有帮助,别忘了点个赞和关注~