A solid yet simple fsm implementation in Swift
- 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
- iOS 8.0+ / Mac OS X 10.9+
- Swift
- Xcode 6.4
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 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
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
To run the example project, clone the repo, and run pod install
from the Example directory first.
enum TurnstileState: String {
case Locked = "Locked"
case Unlocked = "Unlocked"
}
enum TurnstileTransition: String {
case Push = "Push"
case Coin = "Coin"
}
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)
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
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)
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)
if let newState = fsm.transitionWith(.Coin) {
// state change happened
} else {
// transition was not valid
}
You can access the current state of the fsm at any moment. This will return a State
fsm.currentState
Ciprian Caba, cipri@cipriancaba.com
SwiftFSM is available under the MIT license. See the LICENSE file for more info.