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(from: oldValue, to: _state)
var state: P.StateType {
return _state
// Can't be an observer because we need the option to CONDITIONALLY set state
delegateTransitionTo(to: newValue)
init(initialState: P.StateType, delegate: P) {
// Set the primitive to avoid calling the delegate.
_state = initialState
self.delegate = delegate
private func delegateTransitionTo(to: P.StateType) {
switch delegate.shouldTransitionFrom(from: _state, to: to) {
case .Continue:
_state = to
case .Redirect(let newState):
_state = to
state = newState
case .Abort:
protocol StateMachineDelegateProtocol: class {
associatedtype 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
You can’t perform that action at this time.