Swen - 使用 Swift 编写的 Event Bus
- 类型安全的的事件
- 传递自定义对象
- 线程安全
- 粘性事件
- 快速且小巧
入门指南
Swen 可通过 CocoaPods 获得。要安装它,只需将以下行添加到 Podfile 中
pod "Swen"
示例
要运行示例项目,首先克隆仓库,然后从 Example 目录运行 pod install
需求
- iOS 9.0+ / macOS 10.10+ / tvOS 9.0+ / watchOS 2.0+
- Xcode 8.1+
- Swift 3.0+
使用方法
import Swen
struct TestEvent: Event {
let name: String
}
class TestViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//register for incoming events
Swen<TestEvent>.register(self) { event in
print(event.name)
}
//post event
Swen.post(TestEvent(name: "Sixt"))
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
//unregister from events
Swen<TestEvent>.unregister(self)
}
}
在不同的线程上注册
// Registers on the main thread
Swen<Event>.register(_ observer: AnyObject, handler: (_ event: Event) -> Void)
// Registers on background queue
Swen<Event>.registerOnBackground(_ observer: AnyObject, handler: (_ event: Event) -> Void)
// Registers the closure on a specific queue
Swen<Event>.register(_ observer: AnyObject, onQueue queue: OperationQueue, handler: (_ event: Event) -> Void)
粘性事件
有时事件不仅仅对那一刻重要,还需要长时间保存。在这些情况下,粘性事件非常有用。它们的行为与正常事件相同,增加了两个额外功能。首先,您可以通过以下方式查询它们
struct TestStickyEvent: StickyEvent {
let name: String
}
print(Swen<TestStickyEvent>.sticky()?.name)
重要:返回粘性是可选的,因为事件可能尚未发布!
第二个增加的功能是,如果您注册了一个粘性事件,并且在该事件发布之前已经注册了一个,它将立即触发已注册的闭包
class TestViewController: UIViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//post event
Swen.post(TestStickyEvent(name: "Stick it"))
//register for incoming events
Swen<TestStickyEvent>.register(self) { event in
print(event.name)
}
}
}
系统事件
要使用系统事件,为兴趣NSNotifications编写包装器
public struct SystemEvents {
struct ApplicationWillEnterForeground: Event {
}
static func register(storage: SwenStorage = .defaultStorage) {
let center = NotificationCenter.default
center.addObserver(forName: .UIApplicationWillEnterForeground, object: nil, queue: nil) { _ in
Swen.post(ApplicationWillEnterForeground(), in: storage)
}
}
}
依赖注入
为了将测试用例封装在产品代码和彼此之间,我们建议使用依赖注入和存储机制
class TestViewController: UIViewController {
var swenStorage = SwenStorage()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//register for incoming events in custom storage
Swen<TestEvent>.register(self, in: swenStorage) { event in
print(event.name)
}
//register for incoming events in default storage
Swen<TestEvent>.register(self) { event in
print(event.name)
}
//post event in custom storage
Swen.post(TestEvent(name: "Sixt, custom storage"), in: swenStorage)
//post event in default storage
Swen.post(TestEvent(name: "Sixt, default storage"))
}
}
性能
使用Swen的主要其他好处之一是,与NSNotificationCenter相比,性能显著提高
性能测试 | NSNotificationCenter | SwiftBus |
---|---|---|
对1个接收者执行10ˆ6事件 | 6.54秒 | 2.61秒 |
向10ˆ3个接收器执行10ˆ3个事件 | 14.42秒 | 11.15秒 |
作者
- e-Sixt, [email protected]
贡献者
- Дмирий Пوز黄瓜赫夫,[email protected]
- Франц Буш,[email protected]
- 献给斯文·罗德尔
许可协议
Swen可在MIT许可下使用。有关更多信息,请参阅LICENSE文件。