Skip to content

Instantly share code, notes, and snippets.

@lamprosg
Last active December 8, 2019 18:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save lamprosg/ccd6cffa482be92ae7779eb71b19221f to your computer and use it in GitHub Desktop.
Save lamprosg/ccd6cffa482be92ae7779eb71b19221f to your computer and use it in GitHub Desktop.
(iOS) Swift only KVO alternative, event handlers
//Documentation
//https://blog.scottlogic.com/2015/02/05/swift-events.html
//KVO example (not shown in this gist)
//https://blog.scottlogic.com/2015/02/11/swift-kvo-alternatives.html
public class Event<T> {
public typealias EventHandler = T -> ()
private var eventHandlers = [Invocable]()
public func raise(data: T) {
for handler in self.eventHandlers {
handler.invoke(data)
}
}
public func addHandler<U: AnyObject>(target: U,
handler: (U) -> EventHandler) -> Disposable {
let wrapper = EventHandlerWrapper(target: target,
handler: handler, event: self)
eventHandlers.append(wrapper)
return wrapper
}
}
private protocol Invocable: class {
func invoke(data: Any)
}
//----
public protocol Disposable {
func dispose()
}
private class EventHandlerWrapper<T: AnyObject, U>
: Invocable, Disposable {
weak var target: T?
let handler: T -> U -> ()
let event: Event<U>
init(target: T?, handler: T -> U -> (), event: Event<U>) {
self.target = target
self.handler = handler
self.event = event;
}
func invoke(data: Any) -> () {
if let t = target {
handler(t)(data as U)
}
}
func dispose() {
event.eventHandlers =
event.eventHandlers.filter { $0 !== self }
}
}
//----
//Usage:
func someFunction() {
// create an event
let event = Event<(String, String)>()
// add a handler
let handler = event.addHandler(self, ViewController.handleEvent)
// raise the event
event.raise("Colin", "Eberhardt")
// remove the handler
handler.dispose()
}
func handleEvent(data: (String, String)) {
println("Hello \(data.0), \(data.1)")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment