无需Rx
构建数据驱动的UI
我是响应式框架的忠实粉丝。我使用过 RxSwift、ReactiveSwift 和 Combine,但每次加入因某些原因团队无法采用这些框架的项目时,我都感到痛苦。
这个库旨在精简掉所有非必要的东西。实际上,构建数据驱动的 UI 所需的仅仅是可观察属性和事件广播器。而这正是你从这个微框架中获得的一切(仅 100 行代码)
也称为
BehaviorRelay
MutableProperty
CurrentValueSubject
class ViewModel {
@Property var items: [Items] = []
}
// Access the current value:
viewModel.items.count
// Subscribe on changes of the value:
viewModel.$items.observe(with: self) { (obj, items) in
...
}
也称为
PublishRelay
Signal
PassthroughSubject
class ViewModel {
@Signal var didReceiveMessage: Accepts<Message>
}
// Broadcast a notification:
didReceiveMessage.send(message)
// Subscribe on updates:
viewModel.$didReceiveMessage.observe(with: self) { (obj, message) in
...
}
你只需使用 Swift 的访问控制,即可限制从模块外部的写入访问
class ViewModel {
@Property private(set) var value: String = "Minimalist"
@Signal private(set) var signal: Accepts<Void>
}
// Cannot change property or trigger a signal:
viewModel.value = "abc" // ❌
viewModel.signal.send(()) // ❌
订阅绑定到所提供对象的生命周期,并自动分离。该对象也与值一起在回调中提供,因此你无需一直进行 [weak self]
操作
class ViewController: UIViewController {
var tableView: UITableView
func viewDidLoad() {
...
viewModel.$items.observe(with: self) { (vc, items) in
vc.tableView.reloadData()
}
}
}
数据驱动的 UI 在单向数据流设计下效果最佳,这可能涉及到在应用程序中使用集中式状态。
订阅时,你可以指定状态容器内值的 KeyPath
,以接收范围限定和过滤后的更新(类似于 distinctUntilChanged
)
$appState.observe(\.screens.loginScreen, with: self) { (obj, state) in
...
}
专业提示:\.self
也是一个有效的 KeyPath
。这样,在观察原始类型时,你可以丢弃相同的值。
@ Carthage
github "nalexn/minimalist"
@ CocoaPods
pod 'Minimalist'
@ SPM
.package(url: "https://github.com/nalexn/minimalist.git", from: "1.0.0")