Latest 0.1.0
Homepage https://github.com/regexident/EventBus
License BSD-3
Platforms ios 9.0, osx 10.11, watchos 3.0, tvos 10.0
Authors

jumbotron

EventBus

EventBus is a safe-by-default alternative to Cocoa’s NSNotificationCenter. It provides a type-safe API that can safely be used from multiple threads. It automagically removes subscribers when they are deallocated.

EventBus is to one-to-many notifications what a Delegate is to one-to-one notifications.

screencast

Usage

Simple Notifications:

Let’s say you have a lottery that’s supposed to notify all its participating players every time a new winning number is drawn:

import EventBus

protocol LotteryDraw {
    func didDraw(number: Int, in: Lottery)
}

class Lottery {
    private let eventBus = EventBus()

    func add(player: LottoPlayer) {
        self.eventBus.add(subscriber: player, for: LotteryDraw.self)
    }

    func draw() {
        let winningNumber = arc4random()
        self.eventBus.notify(LotteryDraw.self) { subscriber in
            subscriber.didDraw(number: Int(winningNumber), in: self)
        }
    }
}

class LottoPlayer : LotteryDraw {
    func didDraw(number: Int, in: Lottery) {
        if number == 123456 { print("Hooray!") }
    }
}

Complex Notifications:

Nice, but what if you would like to group a set of semantically related notifications (such as different stages of a process) into a common protocol? No problem! Your protocol can be of arbitrary complexity.

Consider this simple key-value-observing scenario:

import EventBus

protocol ValueChangeObserver {
    func willChangeValue(of: Publisher, from: Int, to: Int)
    func didChangeValue(of: Publisher, from: Int, to: Int)
}

class Publisher {
    private let eventBus = EventBus()

    var value: Int {
        willSet {
            self.eventBus.notify(ValueChangeObserver.self) { subscriber in
                subscriber.willChange(value: self.value, to: newValue)
            }
        }
        didSet {
            self.eventBus.notify(ValueChangeObserver.self) { subscriber in
                subscriber.didChange(value: oldValue, to: self.value)
            }
        }
    }

    func add(subscriber: ValueChangeObserver) {
        self.eventBus.add(subscriber: subscriber, for: ValueChangeObserver.self)
    }
}

class Subscriber : ValueChangeObserver {
    func willChangeValue(of: Publisher, from: Int, to: Int) {
        print("(of) will change value from (from) to (to).")
    }

    func didChangeValue(of: Publisher, from: Int, to: Int) {
        print("(of) did change value from (from) to (to).")
    }
}

Chaining

Sometimes it is desirable to have one event bus forward a carbon copy of all of its events to a second event bus. A possible scenario would be a proxy event bus that acts as a centralized facade to an arbitrary number of internal event buses.

let eventBus1 = EventBus()
let eventBus2 = EventBus()
let proxyEventBus = EventBus()
eventBus1.attach(chain: proxyEventBus)
eventBus2.attach(chain: proxyEventBus)

proxyEventBus.add(subscriber: subscriber, for: SomeProtocol.self)

For each event notified on either eventBus1 or eventBus2 a carbon copy will be forwarded to proxyEventBus.

Encapsulation

The API of EventBus is split up into three protocols:

  • EventSubscribable
  • EventChainable
  • EventNotifiable

This enables for ergonomic safe encapsulation …

class Publisher {
    var eventSubscribable: EventSubscribable {
        return self.eventBus
    }

    private let eventBus: EventBus = …

    // …
}

… preventing anybody else from issuing notifications on Publisher‘s event bus.

Installation

The recommended way to add EventBus to your project is via Carthage:

github 'regexident/EventBus'

Or to add EventBus to your project is via CocoaPods:

pod 'Swift-EventBus'

License

EventBus is available under a modified BSD-3 clause license. See the LICENSE file for more info.

Latest podspec

{
    "name": "Swift-EventBus",
    "version": "0.1.0",
    "summary": "A safe-by-default pure Swift notification center.",
    "description": "A safe-by-default pure Swift alternative to Cocoa's `NSNotificationCenter`.",
    "homepage": "https://github.com/regexident/EventBus",
    "license": {
        "type": "BSD-3",
        "file": "LICENSE"
    },
    "authors": {
        "regexident": "[email protected]"
    },
    "source": {
        "git": "https://github.com/regexident/EventBus.git",
        "tag": "0.1.0"
    },
    "platforms": {
        "ios": "9.0",
        "osx": "10.11",
        "watchos": "3.0",
        "tvos": "10.0"
    },
    "source_files": "EventBus/**/*.swift",
    "pushed_with_swift_version": "3.2"
}

Pin It on Pinterest

Share This