Skip to content

Instantly share code, notes, and snippets.

@KelvinJin
Last active October 19, 2016 06:32
Show Gist options
  • Save KelvinJin/4e18fbc156b8ba0abd1491d731538db9 to your computer and use it in GitHub Desktop.
Save KelvinJin/4e18fbc156b8ba0abd1491d731538db9 to your computer and use it in GitHub Desktop.
A class written in Swift that simplifies how notification works in iOS.
class SwiftyBus {
private static let notificationQueue = DispatchQueue(label: "com.swiftybus.notification")
struct Observer {
let callback: Any
let queue: DispatchQueue
}
static let shared = SwiftyBus()
private var pools: [String: [String: Observer]] = [:]
@discardableResult
func register<T>(indexKey: String = UUID().uuidString, queue: DispatchQueue = notificationQueue, observer: @escaping (T) -> Void) -> String {
let key = "\(type(of: T.self))"
var cPool = pools[key] ?? [:]
cPool[indexKey] = Observer(callback: observer, queue: queue)
pools[key] = cPool
return indexKey
}
@discardableResult
func unregister<T>(indexKey: String) -> ((T) -> Void)? {
let key = "\(type(of: T.self))"
guard var cPool = pools[key] else { return nil }
let observer = cPool.removeValue(forKey: indexKey)
pools[key] = cPool
return observer?.callback as? (T) -> Void
}
func notify<T>(object: T) {
let key = "\(type(of: T.self))"
guard let cPool = pools[key] else { return }
cPool.values.forEach { item in
guard let observer = item.callback as? (T) -> Void else { return }
item.queue.async {
observer(object)
}
}
}
}
@KelvinJin
Copy link
Author

Sample Usage

struct Person {
    let name: String
    let age: Int
}

class Publisher {
    init() {}
    func post(person: Person) {
        SwiftyBus.shared.notify(object: person)
    }
}

class Subscriber {
    let token: String

    init(tag: String) {
        token = SwiftyBus.shared.register { (p: Person) -> Void in
            print("SUBSCRIBER \(tag): A new person is coming, \(p.name) at \(p.age)")
        }
    }

    func unregister() {
        let _: ((Person) -> Void)? = SwiftyBus.shared.unregister(indexKey: token)
    }
}

let jin = Person(name: "Jin", age: 25)
let publisher = Publisher()
let google = Subscriber(tag: "Google")
let apple = Subscriber(tag: "Apple")

publisher.post(person: jin)

let sam = Person(name: "Sam", age: 46)
google.unregister()

publisher.post(person: sam)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment