https://github.com/orchetect/swift-state-machines
General-purpose state machine types for Swift.
https://github.com/orchetect/swift-state-machines
ios macos state-machine state-machines statemachine statemachines swift tvos visionos watchos
Last synced: 3 days ago
JSON representation
General-purpose state machine types for Swift.
- Host: GitHub
- URL: https://github.com/orchetect/swift-state-machines
- Owner: orchetect
- License: mit
- Created: 2026-07-06T21:49:37.000Z (24 days ago)
- Default Branch: main
- Last Pushed: 2026-07-14T20:59:26.000Z (16 days ago)
- Last Synced: 2026-07-14T22:28:03.403Z (16 days ago)
- Topics: ios, macos, state-machine, state-machines, statemachine, statemachines, swift, tvos, visionos, watchos
- Language: Swift
- Homepage:
- Size: 159 KB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# SwiftStateMachines
[](https://swiftpackageindex.com/orchetect/swift-state-machines) [](https://swiftpackageindex.com/orchetect/swift-state-machines) [](https://github.com/orchetect/swift-state-machines/blob/main/LICENSE)
General-purpose state machine types for Swift.
This package aims to offer flexible, modern, thread-safe abstractions.
> [!NOTE]
>
> For the time being, this library is under active development and is not considered API-stable.
>
> Prior to release 1.0.0, refactors and new features will likely introduce code-breaking changes along the way.
## Overview
This package provides building blocks to define your own set of states, conditional transition logic, and abstractions to serialize transition changes so that a overlapping calls to the same transition are not repeated.
## Start/Stop State Machine
One of the high-level abstractions available combines all of these building blocks into a general-purpose, ready-to-use object lifecycle manager called `StartStopStateMachine`.
In its most basic form, it acts as a start/stop state machine:
```swift
public class MyService {
private let lifecycle = StartStopStateMachine()
public func start() {
lifecycle.start {
// perform synchronized work to start the service
}
}
public func stop() {
lifecycle.stop {
// perform synchronized work to teardown the service
}
}
}
```
## Managed Resources
The `StartStopStateMachine` type may be specialized to contain resources that are created and prepared during the transition to the **started** state, and torn down during the transition to the **stopped** state.
The lifecycle of the inner resources is managed by the state machine, and concurrent state transitions are serialized to retain the integrity of the state machine and its held resources.
```swift
public class MyService {
private let lifecycle = StartStopStateMachine()
public func start() {
lifecycle.start {
let model = Model()
model.setup()
return model
}
}
public func stop() {
lifecycle.stop { model in
model.teardown()
}
}
}
extension MyService {
private struct Model: Sendable {
var value: Int = 0
init() { }
func setup() { }
func teardown() { }
mutating func increment() { value += 1 }
}
}
```
There are various ways to check the current state and interact with managed resources. These are a few basic examples:
```swift
extension MyService {
public func someActionThatRequiresStartedState() throws {
guard lifecycle.assertState(is: .started) else { throw SomeError() }
// asserts state is started, but we don't need access to the model instance
}
public func readModel() throws {
guard let model = lifecycle.startedResources else { throw SomeError() }
// the started resources are returned as an immutable copy
print(model.value)
}
public func mutateModel() throws {
try lifecycle.withStartedResources { model in
// the started resources are available as mutable `inout` within scope
model.increment()
} wrongState: { throw SomeError() }
}
}
```
The library includes many more methods and types to provide maximum flexibility to fit your implementation requirements.
## Getting Started
This library is available as a Swift Package Manager (SPM) package.
1. Add the **swift-state-machines** repo as a dependency.
```swift
.package(url: "https://github.com/orchetect/swift-state-machines", from: "0.3.0")
```
2. Add **SwiftStateMachines** to your target.
```swift
.product(name: "SwiftStateMachines", package: "swift-state-machines")
```
3. Import **SwiftStateMachines** to use it.
```swift
import SwiftStateMachines
```
## Documentation
Formal documentation is currently a WIP. Complete docs coverage and additional example code is planned for a future releasee.
## Author
Coded by a bunch of 🐹 hamsters in a trenchcoat that calls itself [@orchetect](https://github.com/orchetect).
## License
Licensed under the MIT license. See [LICENSE](https://github.com/orchetect/swift-state-machines/blob/master/LICENSE) for details.
## Community & Support
Please do not email maintainers for technical support. Several options are available for issues and questions:
- Questions and feature ideas can be posted to [Discussions](https://github.com/orchetect/swift-state-machines/discussions).
- If an issue is a verifiable bug with reproducible steps it may be posted in [Issues](https://github.com/orchetect/swift-state-machines/issues).
## Contributions
Contributions are welcome. Posting in [Discussions](https://github.com/orchetect/swift-state-machines/discussions) first prior to new submitting PRs for features or modifications is encouraged.
## Code Quality & AI Contribution Policy
In an effort to maintain a consistent level of code quality and safety, this repository was built by hand and is maintained without the use of AI code generation.
AI-assisted contributions are welcome, but must remain modest in scope, maintain the same degree of quality and care, and be thoroughly vetted before acceptance.