Skip to content

Instantly share code, notes, and snippets.

@roop
Created June 4, 2016 15:37
Show Gist options
  • Save roop/6d251ad10246f8187b313fdfc35f8ee1 to your computer and use it in GitHub Desktop.
Save roop/6d251ad10246f8187b313fdfc35f8ee1 to your computer and use it in GitHub Desktop.
/* This is an alternate responder chain implementation that
DOES NOT work in Swift 2.2, but might in a
hypothetical future version of Swift. */
protocol Command {
}
protocol ResponderChainable {
var nextResponder: ResponderChainable? { get }
}
protocol Responder: ResponderChainable {
associatedtype AssociatedCommand: Command
func canPerformCommand(command: AssociatedCommand) -> Bool
func performCommand(command: AssociatedCommand)
}
extension Responder {
func canPerformCommand(command: Command) -> Bool {
if let command = command as? AssociatedCommand {
return self.canPerformCommand(command)
}
return false
}
func performCommand(command: Command) {
if let command = command as? AssociatedCommand {
self.performCommand(command)
}
}
}
class View {
var superView: View? = nil
}
extension View: ResponderChainable {
var nextResponder: ResponderChainable? { return self.superView }
}
/* Declare commands */
// Copy
struct CopyCommand: Command {
}
protocol CopyResponder: Responder {
func canPerformCommand(command: CopyCommand) -> Bool
func performCommand(command: CopyCommand)
}
// Go Fishing
struct GoFishingCommand: Command {
}
protocol GoFishingResponder: Responder {
func canPerformCommand(command: GoFishingCommand) -> Bool
func performCommand(command: GoFishingCommand)
}
// Declare ability to respond to commands
class MyView: View {
}
extension MyView: CopyResponder { // Error: Can't figure out conformance to Responder
func canPerformCommand(command: CopyCommand) -> Bool {
return true
}
func performCommand(command: CopyCommand) {
print("MyView copy")
}
}
extension MyView: GoFishingResponder {
func canPerformCommand(command: GoFishingCommand) -> Bool {
return true
}
func performCommand(command: GoFishingCommand) {
print("MyView go fishing")
}
}
let v: ResponderChainable = MyView()
v.canPerformCommand(CopyCommand()) // Error because v is not a Responder
(v as? Responder)?.canPerformCommand(CopyCommand()) // Error because can't cast to Responder
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment