Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
A Simple Swift State Machine
import Foundation
class StateMachine<P:StateMachineDelegateProtocol>{
private unowned let delegate:P
private var _state:P.StateType{
delegate.didTransitionFrom(oldValue, to:_state)
var state:P.StateType{
return _state
set{ //Can't be an observer because we need the option to CONDITIONALLY set state
init(initialState:P.StateType, delegate:P){
_state = initialState //set the primitive to avoid calling the delegate.
self.delegate = delegate
private func delegateTransitionTo(to:P.StateType){
switch delegate.shouldTransitionFrom(_state, to:to){
case .Continue:
_state = to
case .Redirect(let newState):
_state = to
state = newState
case .Abort:
protocol StateMachineDelegateProtocol: class{
typealias StateType
func shouldTransitionFrom(from:StateType, to:StateType)->Should<StateType>
func didTransitionFrom(from:StateType, to:StateType)
enum Should<T>{
case Continue, Abort, Redirect(T)
import UIKit
class Example : UIView{
private var machine:StateMachine<Example>!
enum TrafficLight{
case Stop, Go, Caution
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
machine = StateMachine(initialState: .Stop, delegate: self)
@IBAction func tappedGo(sender:AnyObject){
machine.state = .Go
@IBAction func tappedCaution(sender:AnyObject){
machine.state = .Caution
extension Example : StateMachineDelegateProtocol{
typealias StateType = TrafficLight
func shouldTransitionFrom(from: StateType, to: StateType) -> Should<StateType> {
switch (from, to){
case (.Stop, .Go), (.Caution, .Stop):
return .Continue
case (.Go, .Caution):
return .Redirect(.Stop)
return .Abort
func didTransitionFrom(from: StateType, to: StateType) {
switch to{
case .Stop:
backgroundColor = UIColor.redColor()
case .Go:
backgroundColor = UIColor.greenColor()
case .Caution:
backgroundColor = UIColor.yellowColor()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment