SwiftFSM
A solid yet simple fsm implementation in Swift
Features
- Type safety with Hashable enums
- Simple configuration with
Enum
based States and Transitions - Type-safety for States and Transitions using Generics
- Convenient state handling with closures for
onEnter
andonExit
- Delegate implementation for a more generic state handling
- CocoaPods and Carthage support
Requirements
- iOS 8.0+ / Mac OS X 10.9+
- Swift
- Xcode 6.4
Installation
CocoaPods
To integrate SwiftFSM into your Xcode project using CocoaPods, specify it in your Podfile
:
platform :ios, '8.0'
use_frameworks!
pod 'SwiftFSM'
Then, run the following command:
$ pod install
Carthage
Carthage is a decentralized dependency manager that automates the process of adding frameworks to your Cocoa application.
- Detailed instructions to be added once Carthage is supported
Manually
If you prefer not to use either of the aforementioned dependency managers, you can integrate SwiftFSM into your project manually by simply copying SwiftFSM.swift and SwiftFSMState.swift into your project
Usage
Classic turnstile example project
To run the example project, clone the repo, and run pod install
from the Example directory first.
Defining a state
enum TurnstileState: String {
case Locked = "Locked"
case Unlocked = "Unlocked"
}
Defining a transition
enum TurnstileTransition: String {
case Push = "Push"
case Coin = "Coin"
}
Defining the actual fsm
This is the place where you need to define the Hashable
State
and Transition
generics. This will help Xcode determine any compile time errors
You will need to specify the id of the fsm (in case you want to use multiple fsms and log their events)
This is the place where you can enable or disable fsm logging
let fsm = SwiftFSM<TurnstileState, TurnstileTransition>(id: "TurnstileFSM", willLog: false)
Defining a state
Any state you define must be unique
You will receive a reference to the actual SwiftFSMState
implementation when calling fsm.addState
This reference is needed for defining the transitions from that state and for mapping the state handlers
let locked = fsm.addState(.Locked)
// Define an inline onEnter handler
locked.onEnter = { (transition: TurnstileTransition) -> Void in
// called when the locked state defined above is entered. You also receive the type of transition that generated the state change
}
let unlocked = fsm.addState(.Unlocked)
// Define handlers as reference
unlocked.onEnter = handleUnlocked
// Listen to onExit event
unlocked.onExit = handleUnlockedExit
Defining a transition
You obviously need to define transitions between states and in SwiftFSM this comes really natural
locked.addTransition(.Push, to: .Locked)
locked.addTransition(.Coin, to: .Unlocked)
unlocked.addTransition(.Coin, to: .Unlocked)
unlocked.addTransition(.Push, to: .Locked)
Starting the fsm
Once you are happy with the configuration of the fsm, you will need to start it
Please note that this will not trigger the initial onEnter callback
fsm.startFrom(.Locked)
Check if a transition was successful
if let newState = fsm.transitionWith(.Coin) {
// state change happened
} else {
// transition was not valid
}
Current state
You can access the current state of the fsm at any moment. This will return a State
fsm.currentState
Author
Ciprian Caba, cipri@cipriancaba.com
License
SwiftFSM is available under the MIT license. See the LICENSE file for more info.