.claude/skills/fosmvvm-swiftui-app-setup/SKILL.md
Set up the @main App struct for FOSMVVM SwiftUI apps. Configures MVVMEnvironment, deployment URLs, and test infrastructure.
npx skillsauth add foscomputerservices/FOSUtilities fosmvvm-swiftui-app-setupInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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 modulesdeploymentURLs - URLs for each deployment environmentResource 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:
Bundle.module which SPM automatically provides for each moduleThe 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:
default: case@State private var underTest = false flagregisterTestingViews() 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:
init()| Component | Location | Purpose |
|-----------|----------|---------|
| Main App struct | Sources/App/{AppName}.swift | Entry point with MVVMEnvironment setup |
| MVVMEnvironment configuration | Computed property in App struct | Bundles and deployment URLs |
| Test infrastructure | DEBUG blocks in App struct | UI testing support |
| Placeholder | Description | Example |
|-------------|-------------|---------|
| {AppName} | Your app name | MyApp, AccelApp |
| {AppTarget} | Main app target | App |
| {ResourceBundles} | Module names with localization | MyAppViewModels, SharedResources |
Invocation: /fosmvvm-swiftui-app-setup
Prerequisites:
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:
Based on project structure:
If test support needed:
Skill references information from:
The MVVMEnvironment is a computed property, not a stored property:
private var mvvmEnv: MVVMEnvironment {
MVVMEnvironment(
appBundle: Bundle.main,
resourceBundles: [...],
deploymentURLs: [...]
)
}
Why computed?
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?
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:
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.
| Concept | Convention | Example |
|---------|------------|---------|
| App struct | {Name}App | MyApp, AccelApp |
| Main file | {Name}App.swift | MyApp.swift |
| MVVMEnvironment property | mvvmEnv | Always mvvmEnv |
| Test flag | underTest | Always 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:
FOS-DEPLOYMENT = staging| Version | Date | Changes | |---------|------|---------| | 1.0 | 2026-01-23 | Initial skill for SwiftUI app setup | | 1.1 | 2026-01-24 | Update to context-aware approach (remove file-parsing/Q&A). Skill references conversation context instead of asking questions or accepting file paths. |
development
Generate new Claude Code skills following the context-aware pattern. Scaffolds SKILL.md, reference docs, and frontmatter.
testing
Generate ViewModel tests with codable round-trip, versioning stability, and multi-locale translation verification.
data-ai
Generate FOSMVVM ViewModels for SwiftUI screens, pages, and components. Scaffolds RequestableViewModel, localization bindings, and stub factories.
testing
Generate UI tests for FOSMVVM SwiftUI views using XCTest and FOSTestingUI. Covers accessibility identifiers, ViewModelOperations, and test data transport.