Orchestrate iOS app flows — startup gates, data pipelines, and continuous monitors.
ForgeOrchestrator gives you three orchestrators for three common app-flow shapes. Each shares the same action model — identity, priority, shouldRun() gate — but runs them differently.
| Orchestrator | Runs | State sharing | Use case |
|---|---|---|---|
| SequenceOrchestrator | Once | None | App launch gates — onboarding, force-update, terms |
| PipelineOrchestrator | Once | PipelineContext |
Data-loading flows — actions share typed results |
| MonitorOrchestrator | Interval or on-demand | None | Continuous checks — expired terms, periodic sync |
- Three orchestrators for three distinct flow shapes
- Priority-ordered execution —
.critical,.high,.medium,.low - Concurrent gate evaluation —
shouldRun()runs in parallel across all actions @MainActor @Observable— bindisProcessing,eligibleCount,currentActionIddirectly to SwiftUICompletionSignalfor bridging async actions with UI completion callbacks- Screen exclusion on
MonitorOrchestrator— suppress interruption during critical flows
- iOS 18+
- macOS 15+
- Swift 6.3+ (Xcode 26 or later)
- File → Add Package Dependencies…
- Paste
https://github.com/stefanprojchev/ForgeOrchestrator.git - Set rule to Up to Next Major from
1.0.0
dependencies: [
.package(url: "https://github.com/stefanprojchev/ForgeOrchestrator.git", from: "1.0.0")
],
targets: [
.target(
name: "YourApp",
dependencies: ["ForgeOrchestrator"]
)
]import ForgeOrchestrator
struct OnboardingAction: SequenceAction {
let id = ActionID("onboarding")
let priority: ActionPriority = .high
func shouldRun() async -> Bool {
!UserDefaults.standard.bool(forKey: "onboarded")
}
func execute() async {
let signal = CompletionSignal()
OnboardingPresenter.show { signal.complete() }
await signal.wait()
UserDefaults.standard.set(true, forKey: "onboarded")
}
}
// App launch
@main
struct App {
@State private var orchestrator = SequenceOrchestrator()
var body: some Scene {
WindowGroup {
ContentView()
.task {
orchestrator.register([
ForceUpdateAction(),
OnboardingAction(),
WhatsNewAction(),
])
await orchestrator.evaluate()
}
}
}
}import ForgeOrchestrator
struct LoadPostsAction: PipelineAction {
let id: ActionID = "load-posts"
let priority: ActionPriority = .high
func shouldRun() async -> Bool { true }
func execute(context: PipelineContext) async -> ActionResult {
let posts = try? await api.fetchPosts()
context.set("posts", posts ?? [])
return posts != nil ? .completed : .failed("fetch failed")
}
}
struct FilterPostsAction: PipelineAction {
let id: ActionID = "filter-posts"
let priority: ActionPriority = .medium
func shouldRun() async -> Bool { true }
func execute(context: PipelineContext) async -> ActionResult {
guard let posts: [Post] = context.get("posts") else {
return .skipped
}
context.set("filtered", posts.filter(\.isPublished))
return .completed
}
}
let pipeline = PipelineOrchestrator()
pipeline.register([LoadPostsAction(), FilterPostsAction()])
let results = await pipeline.evaluate()import ForgeOrchestrator
let monitor = MonitorOrchestrator(interval: 300) // re-check every 5 minutes
monitor.register(TermsExpiredAction())
monitor.register(SessionTimeoutAction())
// Don't interrupt the user during critical flows
monitor.setExcludedScreens(["Checkout", "VideoCall"])
monitor.start()All three orchestrators are @MainActor @Observable. Bind them directly to SwiftUI:
struct StartupProgress: View {
@Bindable var orchestrator: SequenceOrchestrator
var body: some View {
if orchestrator.isProcessing {
ProgressView(
value: Double(orchestrator.completedCount),
total: Double(orchestrator.eligibleCount)
)
if let id = orchestrator.currentActionId {
Text("Running: \(id.rawValue)")
}
}
}
}- Getting Started
- Action Model — shared protocols,
ActionID,ActionPriority,ActionResult - SequenceOrchestrator · PipelineOrchestrator · MonitorOrchestrator
- CompletionSignal — bridging async actions with UI
ForgeOrchestrator is part of the Forge family of Swift packages for iOS.
| Package | Description |
|---|---|
| ForgeCore | Thread-safe primitives for iOS Swift packages. |
| ForgeInject | Dependency injection with constructor and property wrapper support. |
| ForgeObservers | Reactive system observers — connectivity, lifecycle, keyboard, and more. |
| ForgeStorage | Type-safe key-value, file, and Keychain storage. |
| ForgeOrchestrator | Orchestrate app flows — startup gates, data pipelines, and continuous monitors. |
| ForgePush | Push notification management — permissions, tokens, and routing. |
| ForgeLocation | Location triggers — geofencing, significant changes, and visits. |
| ForgeBackgroundTasks | Background task scheduling and dispatch. |
ForgeOrchestrator is released under the MIT License. See LICENSE.