Latest 1.0.3
Homepage https://github.com/bangerang/SwiftMachine
License MIT
Platforms ios 10.0
Authors

Manage state AND state transitions in a predictable and declarative way with SwiftMachine!

Basic Example

Define your state and state machine:

enum PizzaState: StateMachineDataSource {

    case makingDough
    case addingTopping([Topping])
    case baking
    case eating

    static var initialState: PizzaState = .makingDough

    static func shouldTransition(from: PizzaState, to: PizzaState) -> Bool {
        switch (from, to) {
        case (.makingDough, addingTopping):
            return true
        case (.addingTopping, .baking):
            return true
        case (.baking, .eating):
            return true
        default:
            return false
        }
    }
}

class Pizza: StateMachine<PizzaState> {

    private(set) var topping: [Topping] = []

    override var state: PizzaState {
        didSet {
            // Maybe we want to persist the topping
            if case .addingTopping(let topping) = state {
                self.topping = topping
                print(self.topping) // [salami, onion]
            }
        }
    }
}

Create a new state machine and modify its state:


let pizza = Pizza()

print(pizza.state) // .makingDough since we specified this as the initial state

pizza.state = .addingTopping([salami, onion]]

print(pizza.state) // .addingTopping

pizza.state = .eating

print(pizza.state) // still .addingTopping since transition between .addTopping and .eating is not allowed, you have the bake the pizza first!

pizza.state = .baking 

print(pizza.state) // .baking

pizza.state = .eating

print(pizza.state) // .eating

Listening for state changes:

class ViewController: UIViewController {

  let pizza = Pizza()

  override func viewDidLoad() {
     super.viewDidLoad()
     pizza.addListener(self) // No need to remove listener later since its stored as a weak reference
  }

  func updateUI() {
     switch pizza.state {
        case .makingDough:
            handleDoughUI()
        case .addingTopping(let toppings):
            handleToppingUI(toppings)
        case .baking:
            handleBakingUI()
        case .eating:
            handleEatingUI()
     }
  }

}
extension ViewController: StateListener {
    func stateChanged<T>(for stateMachine: StateMachine<T>) where T : StateMachineDataSource {
        updateUI()
    }
}

Installation

Carthage:

github "bangerang/SwiftMachine"

CocoaPods:

pod 'SwiftMachine'

Credits

Thanks to @jemmons for me inspiring me to build this library, I really recommend you to read his blog about State Machines in Swift.

Latest podspec

{
    "name": "SwiftMachine",
    "version": "1.0.3",
    "summary": "A Finite-like state machine written in Swift",
    "description": "A simple, lightweight, yet powerful way to to manage state and state transitions in your application.",
    "homepage": "https://github.com/bangerang/SwiftMachine",
    "license": {
        "type": "MIT",
        "file": "LICENSE"
    },
    "authors": {
        "bangerang": "[email protected]"
    },
    "source": {
        "git": "https://github.com/bangerang/SwiftMachine.git",
        "tag": "1.0.3"
    },
    "social_media_url": "https://twitter.com/johanthorell",
    "exclude_files": "SwiftMachine/*.plist",
    "swift_version": "3.2",
    "platforms": {
        "ios": "10.0"
    },
    "source_files": "SwiftMachine/**/*"
}

Pin It on Pinterest

Share This