- Typesafe events
- Pass custom objects
- Threadsafe
- Sticky events
- Fast and small
Swen is available through CocoaPods, Carthage and Swift Package Manager.
To install it using CocoaPods, simply add the following line to your Podfile:
pod "Swen"
To install it via Carthage, add the following line to your Cartfile and follow the instructions to adding frameworks to an application:
github "e-Sixt/Swen"
To install it using the Swift Package Manager, either directly add it to your project using Xcode 11, or specify it as dependency in the Package.swift file:
// ...
dependencies: [
.package(url: "https://github.com/e-Sixt/Swen.git", from: "2.0.0"),
],
//...
To run the example project, clone the repo, and run pod install
from the Example directory first.
- 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)
Sometimes events carry information that is not only important for that one moment but needs to be kept around longer. For these cases sticky events come in handy. They behave the same as normal events with two further additions. First you can query them by:
struct TestStickyEvent: StickyEvent {
let name: String
}
print(Swen<TestStickyEvent>.sticky()?.name)
Important: The return sticky is optional, because the event may not be posted yet!
The second additions is that if you register for a sticky event and one was already posted before. It will immediately trigger the registered closure
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)
}
}
}
To use System Events, write wrapper for interest 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)
}
}
}
To encapsulate test cases from production code and from each other, we suggest to use Dependency Injection and Storage mechanism:
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"))
}
}
One of the other main benefits of using Swen is the significant performance increase over NSNotificationCenter
Performance Test | NSNotificationCenter | SwiftBus |
---|---|---|
Perform 10ˆ6 Events to 1 receiver | 6.54s | 2.61s |
Perform 10ˆ3 Events to 10ˆ3 receivers | 14.42s | 11.15s |
- e-Sixt, sixtlabs@sixt.com
- Dmitry Poznukhov, dmitry.poznukhov@sixt.com
- Franz Busch, franz-joseph.busch@sixt.com
- Dedicated to Sven Röder
Swen is available under the MIT license. See the LICENSE file for more info.