Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
Set up a SwiftUI @main App struct with MVVMEnvironment configuration, deployment URLs, resource bundles, environment injection, and DEBUG test infrastructure.
Set up a SwiftUI @main App struct with MVVMEnvironment configuration, deployment URLs, resource bundles, environment injection, and DEBUG test infrastructure.
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete.
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run.
Generate the main App struct for a SwiftUI application using FOSMVVM architecture.
For full architecture context, see FOSMVVMArchitecture.md | OpenClaw reference The App struct is the entry point of a SwiftUI application. In FOSMVVM, it has three core responsibilities: βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β @main App Struct β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€ β 1. MVVMEnvironment Setup β β - Bundles (app + localization resources) β β - Deployment URLs (production, staging, debug) β β β β 2. Environment Injection β β - .environment(mvvmEnv) on WindowGroup β β - Custom environment values β β β β 3. Test Infrastructure (DEBUG only) β β - .testHost { } modifier for UI testing β β - registerTestingViews() for individual view testing β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
The MVVMEnvironment provides FOSMVVM infrastructure to all views: private var mvvmEnv: MVVMEnvironment { MVVMEnvironment( appBundle: Bundle.main, resourceBundles: [ MyAppViewModelsResourceAccess.localizationBundle, SharedResourceAccess.localizationBundle ], deploymentURLs: [ .production: .init(serverBaseURL: URL(string: "https://api.example.com")!), .debug: .init(serverBaseURL: URL(string: "http://localhost:8080")!) ] ) } Key configuration: appBundle - Usually Bundle.main (the app bundle) resourceBundles - Array of localization bundles from your modules deploymentURLs - URLs for each deployment environment Resource Bundle Accessors: Each module that contains localization resources should provide a bundle accessor: // In your ViewModels module (e.g., MyAppViewModels/ResourceAccess.swift) public enum MyAppViewModelsResourceAccess { public static var localizationBundle: Bundle { Bundle.module } } This pattern: Uses Bundle.module which SPM automatically provides for each module Provides a clean public API for accessing the module's resources Keeps bundle access centralized in one place per module
The MVVMEnvironment is injected at the WindowGroup level: var body: some Scene { WindowGroup { MyView() } .environment(mvvmEnv) // β Makes FOSMVVM infrastructure available } This makes the environment available to all views in the hierarchy.
The test infrastructure enables UI testing with specific configurations: .testHost { } modifier: var body: some Scene { WindowGroup { ZStack { LandingPageView() } #if DEBUG .testHost { testConfiguration, testView in // Handle specific test configurations... default: testView .onAppear { underTest = ProcessInfo.processInfo.arguments.count > 1 } } #endif } } Key points: Apply to the top-level view in WindowGroup (the outermost view in your hierarchy) This ensures the modifier wraps the entire view hierarchy to intercept test configurations Always include the default: case The default case detects test mode via process arguments Sets @State private var underTest = false flag Optional: Add specific test configurations for advanced scenarios registerTestingViews() function: #if DEBUG private extension MyApp { @MainActor func registerTestingViews() { mvvmEnv.registerTestView(LandingPageView.self) mvvmEnv.registerTestView(SettingsView.self) // ... register all ViewModelViews for individual testing } } #endif Key points: Extension on the App struct (not MVVMEnvironment) Called from init() Registers every ViewModelView for isolated testing DEBUG only
Starting a new FOSMVVM SwiftUI application Migrating an existing SwiftUI app to FOSMVVM Setting up the App struct with proper FOSMVVM infrastructure Configuring test infrastructure for UI testing
ComponentLocationPurposeMain App structSources/App/{AppName}.swiftEntry point with MVVMEnvironment setupMVVMEnvironment configurationComputed property in App structBundles and deployment URLsTest infrastructureDEBUG blocks in App structUI testing support
PlaceholderDescriptionExample{AppName}Your app nameMyApp, AccelApp{AppTarget}Main app targetApp{ResourceBundles}Module names with localizationMyAppViewModels, SharedResources
Invocation: /fosmvvm-swiftui-app-setup Prerequisites: App name understood from conversation context Deployment URLs discussed or documented Resource bundles identified (modules with localization) Test support requirements clarified Workflow integration: This skill is used when setting up a new FOSMVVM SwiftUI application or adding FOSMVVM infrastructure to an existing app. The skill references conversation context automaticallyβno file paths or Q&A needed.
This skill references conversation context to determine App struct configuration:
From conversation context, the skill identifies: App name (from project discussion or existing code) Deployment environments (production, staging, debug URLs) Resource bundles (modules containing localization YAML files) Test infrastructure (whether UI testing support needed)
Based on project structure: App bundle (typically Bundle.main) Resource bundle accessors (from identified modules) Deployment URLs (for each environment) Current version (from shared module)
If test support needed: Test detection (process arguments check) Test host modifier (wrapping top-level view) View registration (all ViewModelViews for testing)
Main App struct with @main attribute MVVMEnvironment computed property WindowGroup with environment injection Test infrastructure (if requested, DEBUG-only) registerTestingViews() extension (if test support)
Skill references information from: Prior conversation: App requirements, deployment environments discussed Project structure: From codebase analysis of module organization Existing patterns: From other FOSMVVM apps if context available
The MVVMEnvironment is a computed property, not a stored property: private var mvvmEnv: MVVMEnvironment { MVVMEnvironment( appBundle: Bundle.main, resourceBundles: [...], deploymentURLs: [...] ) } Why computed? Keeps initialization logic separate Can be customized in DEBUG vs RELEASE Clear dependency on bundles and URLs
The default test detection uses process arguments: @State private var underTest = false // In .testHost default case: testView .onAppear { // Right now there's no other way to detect if the app is under test. // This is only debug code, so we can proceed for now. underTest = ProcessInfo.processInfo.arguments.count > 1 } Why this approach? Simple and reliable for DEBUG builds No additional dependencies Process arguments are set by test runner
Every ViewModelView should be registered for testing: @MainActor func registerTestingViews() { // Landing Page mvvmEnv.registerTestView(LandingPageView.self) // Settings mvvmEnv.registerTestView(SettingsView.self) mvvmEnv.registerTestView(ProfileView.self) // Dashboard mvvmEnv.registerTestView(DashboardView.self) mvvmEnv.registerTestView(CardView.self) } Organization tips: Group by feature/screen with comments Alphabetical order within groups One view per line for easy scanning
You can inject multiple environment values: var body: some Scene { WindowGroup { MyView() } .environment(mvvmEnv) .environment(appState) .environment(\.colorScheme, .dark) .environment(\.customValue, myCustomValue) }
You can conditionally register views based on build configuration: #if DEBUG @MainActor func registerTestingViews() { mvvmEnv.registerTestView(LandingPageView.self) #if INCLUDE_ADMIN_FEATURES mvvmEnv.registerTestView(AdminPanelView.self) #endif } #endif
You can add specific test configurations in .testHost: .testHost { testConfiguration, testView in switch try? testConfiguration.fromJSON() as MyTestConfiguration { case .specificScenario(let data): testView.environment(MyState.stub(data: data)) .onAppear { underTest = true } default: testView .onAppear { underTest = ProcessInfo.processInfo.arguments.count > 1 } } }
See reference.md for complete file templates.
ConceptConventionExampleApp struct{Name}AppMyApp, AccelAppMain file{Name}App.swiftMyApp.swiftMVVMEnvironment propertymvvmEnvAlways mvvmEnvTest flagunderTestAlways underTest
FOSMVVM supports deployment detection via Info.plist: CI Pipeline Sets: FOS_DEPLOYMENT build setting (e.g., "staging" or "production") β Info.plist Contains: FOS-DEPLOYMENT = $(FOS_DEPLOYMENT) β Runtime Detection: FOSMVVM.Deployment.current reads from Bundle.main.infoDictionary Local development override: Edit Scheme β Run β Arguments β Environment Variables Add: FOS-DEPLOYMENT = staging
Architecture Patterns - Mental models and patterns FOSMVVMArchitecture.md - Full FOSMVVM architecture fosmvvm-viewmodel-generator - For creating ViewModels reference.md - Complete file templates
VersionDateChanges1.02026-01-23Initial skill for SwiftUI app setup1.12026-01-24Update to context-aware approach (remove file-parsing/Q&A). Skill references conversation context instead of asking questions or accepting file paths.
Code helpers, APIs, CLIs, browser automation, testing, and developer operations.
Largest current source with strong distribution and engagement signals.