fosmvvm-swiftui-app-setup

Set up the @main App struct for FOSMVVM SwiftUI apps. Configures MVVMEnvironment, deployment URLs, and test infrastructure.

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "fosmvvm-swiftui-app-setup" with this command: npx skills add foscomputerservices/fosmvvm-swiftui-app-setup

FOSMVVM SwiftUI App Setup

Generate the main App struct for a SwiftUI application using FOSMVVM architecture.

Conceptual Foundation

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    │
└─────────────────────────────────────────────────────────────┘

Core Components

1. MVVMEnvironment

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

2. Environment Injection

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.

3. Test Infrastructure

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

When to Use This Skill

  • 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

What This Skill Generates

ComponentLocationPurpose
Main App structSources/App/{AppName}.swiftEntry point with MVVMEnvironment setup
MVVMEnvironment configurationComputed property in App structBundles and deployment URLs
Test infrastructureDEBUG blocks in App structUI testing support

Project Structure Configuration

PlaceholderDescriptionExample
{AppName}Your app nameMyApp, AccelApp
{AppTarget}Main app targetApp
{ResourceBundles}Module names with localizationMyAppViewModels, SharedResources

How to Use This Skill

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.

Pattern Implementation

This skill references conversation context to determine App struct configuration:

Configuration Detection

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)

MVVMEnvironment Setup

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)

Test Infrastructure Planning

If test support needed:

  • Test detection (process arguments check)
  • Test host modifier (wrapping top-level view)
  • View registration (all ViewModelViews for testing)

File Generation

  1. Main App struct with @main attribute
  2. MVVMEnvironment computed property
  3. WindowGroup with environment injection
  4. Test infrastructure (if requested, DEBUG-only)
  5. registerTestingViews() extension (if test support)

Context Sources

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

Key Patterns

MVVMEnvironment as Computed Property

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

Test Detection Pattern

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

Register All ViewModelViews

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

Common Customizations

Multiple Environment Values

You can inject multiple environment values:

var body: some Scene {
    WindowGroup {
        MyView()
    }
    .environment(mvvmEnv)
    .environment(appState)
    .environment(\.colorScheme, .dark)
    .environment(\.customValue, myCustomValue)
}

Conditional Test Registration

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

Advanced Test Configurations

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
            }
    }
}

File Templates

See reference.md for complete file templates.

Naming Conventions

ConceptConventionExample
App struct{Name}AppMyApp, AccelApp
Main file{Name}App.swiftMyApp.swift
MVVMEnvironment propertymvvmEnvAlways mvvmEnv
Test flagunderTestAlways underTest

Deployment Configuration

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

See Also

Version History

VersionDateChanges
1.02026-01-23Initial skill for SwiftUI app setup
1.12026-01-24Update to context-aware approach (remove file-parsing/Q&A). Skill references conversation context instead of asking questions or accepting file paths.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

Huo15 Openclaw Wechat Service

OpenClaw 微信服务号(公众号)渠道插件 v2.2.0 —— 新增**角色权限系统**:permissionMode='role-based' 支持 superadmin/admin/editor/operator/customer 五级角色,自由配置 rolePermissions 白名单;**AI 对话...

Registry SourceRecently Updated
General

AIWolfPK - AI狼人杀

四个AI互相猜疑,你坐着看戏。每局30秒,到底谁是狼? Four AIs play Werewolf while you watch. 30s per round. Spot the wolf before they do.

Registry SourceRecently Updated
General

Hot Content Creator

热点内容创作助手:自动抓取多平台热点,筛选创作方向,生成小红书封面图和虚拟博主形象, 写出有人味的爆款内容。触发词:热点创作、追热点、创作方向、小红书方向、抖音方向。 适用场景:需要从热点中挖掘内容创作方向并生成配图+文案的完整工作流。

Registry SourceRecently Updated
General

飞书 Markdown 文档发布器,完美支持支持图片、表格

将 Markdown 文件发布为飞书(Feishu/Lark)在线文档。 支持完整的 Markdown 语法,包括标题、段落、表格、有序/无序列表、 待办事项、分隔线、加粗/斜体等富文本样式。 当用户需要将本地 Markdown 文件同步或发布到飞书文档时使用。

Registry SourceRecently Updated