home / skills / hoangnguyen0403 / agent-skills-standard / swiftui

swiftui skill

/skills/ios/swiftui

This skill helps you implement SwiftUI with composable views, proper state management, and data flow for smooth 60fps iOS UI.

npx playbooks add skill hoangnguyen0403/agent-skills-standard --skill swiftui

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
1.2 KB
---
name: SwiftUI Expert
description: Standards for declarative UI construction and data flow in iOS.
metadata:
  labels: [ios, swiftui, ui]
  triggers:
    files: ['**/*View.swift']
    keywords: [View, State, Binding, EnvironmentObject]
---

# SwiftUI Expert

## **Priority: P0 (CRITICAL)**

**You are an iOS UI Expert.** Prioritize smooth 60fps rendering and clean data flow.

## Implementation Guidelines

- **Views**: Small, composable `structs`. Extract subviews often.
- **State**: Use `@State` for local simple data, `@StateObject` for VMs.
- **Modifiers**: Order matters. Apply layout modifiers before visual ones.
- **Preview**: Always provide a `PreviewProvider`.

## Verification Checklist (Mandatory)

- [ ] **Body Property**: Is `body` computationally cheap? (No complex logic).
- [ ] **State Flow**: `@StateObject` initialized only once (in parent)?
- [ ] **Identity**: Do Lists/ForEach have stable `id`?
- [ ] **Main Thread**: Are UI updates strictly on Main Actor?

## Anti-Patterns

- **No Logic in Body**: Move calculations to ViewModel or computed vars.
- **No ObservedObject Init**: Do NOT init `@ObservedObject` inside View init settings.
- **No Hardcoded Sizes**: Use flexible frames and spacers.

Overview

This skill captures SwiftUI standards for declarative UI construction and predictable data flow in iOS apps. It prioritizes smooth 60fps rendering, clear view composition, and safe state management. Use it to enforce performant, maintainable SwiftUI code across components and teams.

How this skill works

The skill inspects view structs, state declarations, modifier ordering, and preview presence to detect common mistakes. It verifies that heavy computation is kept out of body, @StateObject is initialized only once, ForEach/List items use stable ids, and UI updates occur on the main actor. It flags anti-patterns like hardcoded sizes, logic inside body, and improper observed object initialization.

When to use it

  • During code reviews for SwiftUI screens and components.
  • When introducing or refactoring view models and state ownership.
  • Before merging features that affect rendering or scrolling performance.
  • When auditing app-wide UI threading and main-actor compliance.
  • While establishing team UI standards for new SwiftUI projects.

Best practices

  • Keep Views small and composable; extract subviews to reduce body complexity.
  • Use @State for local, simple view state and @StateObject for view models owned by a view.
  • Initialize @StateObject once at the owning parent; do not initialize @ObservedObject inside a view.
  • Order modifiers intentionally: apply layout modifiers before visual ones to avoid layout recalculation.
  • Provide a PreviewProvider for every screen or component to enable rapid iteration and visual checks.

Example use cases

  • Refactor a complex SwiftUI screen: split body into composable subviews and move logic to a ViewModel.
  • Fix a scrolling performance issue by ensuring body is cheap and heavy work runs off the main thread.
  • Enforce stable list identity by adding explicit ids to ForEach/List items to prevent view reuse bugs.
  • Audit a codebase for state ownership issues and convert improper @ObservedObject initializations to parent-owned @StateObject.
  • Add previews and sample data for reusable components to speed up design validation.

FAQ

What counts as expensive work in body?

Any CPU-heavy computation, synchronous data parsing, network calls, or large collection transforms. Move these to a ViewModel, async tasks, or computed properties that cache results.

How do I ensure UI updates run on the main thread?

Annotate view models and mutating methods with @MainActor or dispatch UI updates to the main actor using Task { @MainActor in ... } or DispatchQueue.main.async.