SwiftMachine
使用 SwiftMachine 以可预测和声明式的方式进行状态和状态转换!
基本示例
定义您的状态和状态机
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]
}
}
}
}
创建一个新的状态机并修改其状态
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
监听状态变化
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 {
switch stateMachine {
case _ as Pizza:
updateUI()
default:
assert(false)
}
}
}
安装
Carthage
github "bangerang/SwiftMachine"
CocoaPods
pod 'SwiftMachine'
致谢
感谢 @jemmons 启发我构建这个库,我强烈推荐您阅读他的关于 Swift 中状态机的博客 http://www.figure.ink/blog/2015/1/31/swift-state-machines-part-1。