Skip to content

Instantly share code, notes, and snippets.

@wildthink
Last active September 26, 2018 23:10
Show Gist options
  • Save wildthink/acfdf82c2625dc73ad6e42d399d91846 to your computer and use it in GitHub Desktop.
Save wildthink/acfdf82c2625dc73ad6e42d399d91846 to your computer and use it in GitHub Desktop.
//
// Relay.swift
// XjSwiftLab
//
// Created by Jason Jobe on 5/11/15.
// Copyright (c) 2015, 2016 Jason Jobe. All rights reserved.
// https://gist.github.com/wildthink/acfdf82c2625dc73ad6e42d399d91846
//
/* Example usage
protocol SomeClassOrProtocol.self) {
func someClassOrProtocolFunction (some:Int, args:[String])
}
relay (SomeClassOrProtocol.self) {
$0.someClassOrProtocolFunction(some, args)
}
relay { (target: SomeClassOrProtocol) in
target.someClassOrProtocolFunction(some, args)
}
protocol Demo {}
let app = Application.shared
let demo = app.relay(type: Demo.self)
let demo2: Demo? = app.relay()
*/
import Foundation
#if os(iOS)
import UIKit.UIResponder
public typealias Responder = UIResponder
public typealias Application = UIApplication
#else
import AppKit.NSResponder
public typealias Responder = NSResponder
public typealias Application = NSApplication
#endif
public extension NSObjectProtocol where Self: Responder
{
func relay <T> (type: T.Type, call: (T) -> Void) -> Void {
if let target = relay(type: type) { call (target) }
}
func relay <T> (type: T.Type, if test: (T) -> Bool, call: (T) -> Void) -> Void {
if let target = relay(type: type) { call (target) }
}
func relay<T>() -> T? {
if let target = relay(type: T.self) { return target }
return nil
}
func relay <T> (type: T.Type, if test: ((T) -> Bool)? = nil) -> T?
{
var next: Responder? = self
while next != nil {
if let t = next as? T, test?(t) ?? true {
return t
}
next = next?.next
}
if let t = Application.shared.delegate as? T, test?(t) ?? true {
return t
}
return nil
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment