Skip to content

Instantly share code, notes, and snippets.

@wildthink
Last active March 29, 2016 21:12
Show Gist options
  • Save wildthink/19d43871964821c4f293 to your computer and use it in GitHub Desktop.
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.
//
// 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