🗼
Rasat
Swtif中的pub-sub/observer模式实现的微库。
- 动机
- 相关文章:在Swift中使用Channels进行数据流
组件
📻
通道通道就是一个可以广播消息的事件总线。
enum UserEvent {
case loggedIn(id: String)
case loggedOut(id: String)
}
// Define a channel:
let userChannel = Channel<UserEvent>()
// Broadcast a message:
userChannel.broadcast(.loggedIn(id: "gokselkk"))
👁
可观察对象可观察对象使您能够监听通道上的消息。
// Listen for changes:
let subscription = userChannel.observable.subscribe { event in
self.handleUserEvent(event)
}
// End the subscription when needed:
subscription.dispose()
📦
主题主题封装了一个值,并在变化时进行广播。
enum Theme {
case light, dark
}
// Define a subject:
let themeSubject = Subject(Theme.light)
// Listen for changes:
themeSubject.observable.subscribe { theme in
self.updateTheme(theme)
}
// Update the value:
themeSubject.value = .dark
🏰
示例监听视图控制器中的主题变更
class ThemeManager {
var observable: Observable<Theme> {
return channel.observable
}
private let channel = Channel<Theme>()
func updateTheme(_ theme: Theme) {
channel.broadcast(theme)
}
}
class FeedViewController: UIViewController {
var themeManager: ThemeManager!
private let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
disposeBag += themeManager.observable.subscribe { theme in
self.updateTheme(theme)
}
}
注意:DisposeBag
是一个集合,包含了订阅(或可处理)对象,需要在视图控制器生命周期内存在。在这个例子中,当视图控制器解除分配时,订阅对象会与DisposeBag
一起被销毁。
动机
Apple框架广泛使用代理和观察者模式来传递信息。
- 代理模式适用于一对一、双向通信。它被用来将工作委托给其他组件。
- 观察者模式适用于一对一、单向通信。它被用来观察对象上的更改。
观察者模式的一些用法示例:
UIApplication
发布willEnterForegroundNotification
。UIResponder
发布keyboardDidShowNotification
。
不要忘了,所有这些都在NotificationCenter.default
实例上发生。这正是NotificationCenter
的缺点所在。
- 任何来源的任何通知都可以发布到它上面。
post(...)
和userInfo
API都不是类型安全的。这导致了许多样板代码。- API不提倡关注点的分离。
Rasat旨在解决这些问题,并提供更多功能。
类型安全
Channel
是类型安全的。类型安全也可以限制开发者为每种消息类型创建不同的通道,因此促进关注点的分离。
例如,键盘事件可以这样实现
enum KeyboardEvent {
case didShow(frame: CGRect)
case didDismiss(frame: CGRect)
}
let keyboardChannel = Channel<KeyboardEvent>()
// ...
let subscription = keyboardChannel.observable.subscribe { event in
// Handle event here.
}
Observable
仅观察API与NotificationCenter
提供统一的API用于广播和观察。如果您有一个NotificationCenter
实例,您可以通过它广播或观察,没有限制。
这导致了几个问题
- 有可能出错。某些对象只会被期望观察,而不是广播。使用纯
NotificationCenter
API无法实施这种限制。 - 这降低了可读性。难以区分广播者和观察者。
例如
let center = NotificationCenter.default
// The object that posts notifications on given center:
let broadcaster = Broadcaster(notificationCenter: center)
// The object that observes notifications on given center:
let observer = Observer(notificationCenter: center)
在这一刻,我们只是希望观察者不在给定的通知中心发布任何内容,而只观察广播者发布的通知。
可以使用Channel
和Observable
对以更安全、更方便的方式呈现
let channel = Channel<Message>()
let broadcaster = Broadcaster(channel: channel)
let observer = Observer(observable: channel.observable)
甚至更好,Broadcaster
可以创建一个内部通道并使其观察者公开
let broadcaster = Broadcaster()
let observer = Observer(observable: broadcaster.observable)
安装
CocoaPods
使用将以下行添加到您的Podfile
中
pod 'Rasat'
Carthage
使用将以下行添加到您的Cartfile
中
github "gokselkoksal/Rasat"
手动安装
将Sources
文件夹拖到您的项目中。
强烈建议使用如CocoaPods
或Carthage
之类的依赖管理器。
许可证
Rasat提供MIT许可证。