FI
ForgeOrchestrator

SwiftUI Integration

A RootView driven by an @Observable orchestrator. Startup actions control which screen renders via shared state.

App State

An @Observable singleton holds the flags and CompletionSignal references that actions write to inside execute(). Views read from it to decide what to display.

TaskFlowState.swift
import SwiftUI
import ForgeOrchestrator

@Observable
final class TaskFlowState {
    static let shared = TaskFlowState()

    var showOnboarding = false
    var onboardingSignal: CompletionSignal?

    var showForceUpdate = false
    var forceUpdateSignal: CompletionSignal?
}

RootView

The root view observes TaskFlowState and renders the appropriate screen. The .task modifier registers and evaluates actions — they run once when the view appears. register() is synchronous; only evaluate() needs await.

RootView.swift
import SwiftUI
import ForgeOrchestrator

struct RootView: View {
    @Environment(SequenceOrchestrator.self) var orchestrator
    @State private var state = TaskFlowState.shared

    var body: some View {
        Group {
            if state.showForceUpdate {
                ForceUpdateView(signal: state.forceUpdateSignal)
            } else if state.showOnboarding {
                OnboardingView(signal: state.onboardingSignal)
            } else {
                MainTabView()
            }
        }
        .task {
            // register() is @MainActor and synchronous — only evaluate() needs await
            orchestrator.register(ForceUpdateAction())
            orchestrator.register(OnboardingAction())
            await orchestrator.evaluate()
        }
    }
}

OnboardingView

Receives the CompletionSignal as a parameter — the action created it inside execute() and stored it on shared state. On "Get Started", the view updates state and calls signal.complete(), which resumes the orchestrator and allows the next action to run.

OnboardingView.swift
struct OnboardingView: View {
    let signal: CompletionSignal?

    var body: some View {
        NavigationStack {
            VStack(spacing: 24) {
                Text("Welcome to TaskFlow")
                    .font(.largeTitle.bold())

                Text("Organize your tasks, hit your goals.")
                    .multilineTextAlignment(.center)
                    .foregroundStyle(.secondary)

                Spacer()

                Button("Get Started") {
                    UserDefaults.standard.set(true, forKey: "onboardingComplete")
                    TaskFlowState.shared.showOnboarding = false
                    signal?.complete()
                }
                .buttonStyle(.borderedProminent)
            }
            .padding(32)
        }
    }
}

App Entry Point

Create the orchestrator once in App and inject it into the environment. RootView handles all registration and evaluation via its own .task.

TaskFlowApp.swift
import SwiftUI
import ForgeOrchestrator

@main
struct TaskFlowApp: App {
    @State private var orchestrator = SequenceOrchestrator()

    var body: some Scene {
        WindowGroup {
            RootView()
                .environment(orchestrator)
        }
    }
}