Last active
March 29, 2016 21:12
-
-
Save wildthink/19d43871964821c4f293 to your computer and use it in GitHub Desktop.
Relay offers a Swift, type safe way to find a conforming target along the Responder chain and invoke any protocol method on it.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Relay.swift | |
// XjSwiftLab | |
// | |
// Created by Jason Jobe on 5/11/15. | |
// Copyright (c) 2015 Jason Jobe. All rights reserved. | |
// https://gist.github.com/wildthink/19d43871964821c4f293 | |
// | |
import Foundation | |
/* Examle 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 Relay | |
{ | |
func relay <T> (type: T.Type, from: Any?, @noescape call: (T) -> Void) -> Void | |
func nextRelay() -> Relay? | |
func willPerformRelay <T> (type: T.Type, sender: Any) -> Bool | |
} | |
extension Relay { | |
func relay <T> (type: T.Type, from: Any? = nil, @noescape call: (T) -> Void) -> Void | |
{ | |
if willPerformRelay(type, sender: from) { | |
if let target = self as? T { | |
call (target) | |
} | |
} | |
else { | |
nextRelay()?.relay(type, from: from ?? self, call: call) | |
} | |
} | |
func nextRelay() -> Relay? { | |
return nil | |
} | |
func willPerformRelay <T> (type: T.Type, sender: Any) -> Bool { | |
return self is T | |
} | |
} | |
#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 | |
extension Responder : Relay | |
{ | |
func nextRelay() -> Relay? { | |
let next = nextResponder() ?? Application.sharedApplication() | |
return next | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment