Agent skill

swiftui-patterns

Use when implementing iOS 17+ SwiftUI patterns: @Observable/@Bindable, MVVM architecture, NavigationStack, lazy loading, UIKit interop, accessibility (VoiceOver/Dynamic Type), async operations (.task/.refreshable), or migrating from ObservableObject/@StateObject.

Stars 187
Forks 13

Install this agent skill to your Project

npx add-skill https://github.com/johnrogers/claude-swift-engineering/tree/main/plugins/swift-engineering/skills/swiftui-patterns

SKILL.md

SwiftUI Patterns (iOS 17+)

SwiftUI 17+ removes ObservableObject boilerplate with @Observable, simplifies environment injection with @Environment, and introduces task-based async patterns. The core principle: use Apple's modern APIs instead of reactive libraries.

Overview

Quick Reference

Need Use (iOS 17+) NOT
Observable model @Observable ObservableObject
Published property Regular property @Published
Own state @State @StateObject
Passed model (binding) @Bindable @ObservedObject
Environment injection environment(_:) environmentObject(_:)
Environment access @Environment(Type.self) @EnvironmentObject
Async on appear .task { } .onAppear { Task {} }
Value change onChange(of:initial:_:) onChange(of:perform:)

Core Workflow

  1. Use @Observable for model classes (no @Published needed)
  2. Use @State for view-owned models, @Bindable for passed models
  3. Use .task { } for async work (auto-cancels on disappear)
  4. Use NavigationStack with NavigationPath for programmatic navigation
  5. Apply .accessibilityLabel() and .accessibilityHint() to interactive elements

Reference Loading Guide

ALWAYS load reference files if there is even a small chance the content may be required. It's better to have the context than to miss a pattern or make a mistake.

Reference Load When
Observable Creating new @Observable model classes
State Management Deciding between @State, @Bindable, @Environment
Environment Injecting dependencies into view hierarchy
View Modifiers Using onChange, task, or iOS 17+ modifiers
Migration Guide Updating iOS 16 code to iOS 17+
MVVM Observable Setting up view model architecture
Navigation Programmatic or deep-link navigation
Performance Lists with 100+ items or excessive re-renders
UIKit Interop Wrapping UIKit components (WKWebView, PHPicker)
Accessibility VoiceOver, Dynamic Type, accessibility actions
Async Patterns Loading states, refresh, background tasks
Composition Reusable view modifiers or complex conditional UI

Common Mistakes

  1. Over-using @Bindable for passed models — Creating @Bindable for every property causes unnecessary view reloads. Use @Bindable only for mutable model properties that need two-way binding. Read-only computed properties should use regular properties.

  2. State placement errors — Putting model state in the view instead of a dedicated @Observable model causes view logic to become tangled. Always separate model and view concerns.

  3. NavigationPath state corruption — Mutating NavigationPath incorrectly can leave it in inconsistent state. Use navigationDestination(for:destination:) with proper state management to avoid path corruption.

  4. Missing .task cancellation.task handles cancellation on disappear automatically, but nested Tasks don't. Complex async flows need explicit cancellation tracking to avoid zombie tasks.

  5. Ignoring environment invalidation — Changing environment values at parent doesn't invalidate child views automatically. Use @Environment consistently and understand when re-renders happen based on observation.

  6. UIKit interop memory leaksUIViewRepresentable and UIViewControllerRepresentable can leak if delegate cycles aren't broken. Weak references and explicit cleanup are required.

Expand your agent's capabilities with these related and highly-rated skills.

johnrogers/claude-swift-engineering

swiftui-advanced

Use when implementing gesture composition (simultaneous, sequenced, exclusive), adaptive layouts (ViewThatFits, AnyLayout, size classes), or choosing architecture patterns (MVVM vs TCA vs vanilla, State-as-Bridge). Covers advanced SwiftUI patterns beyond basic views.

187 13
Explore
johnrogers/claude-swift-engineering

ios-hig

Use when designing iOS interfaces, implementing accessibility (VoiceOver, Dynamic Type), handling dark mode, ensuring adequate touch targets, providing animation/haptic feedback, or requesting user permissions. Apple Human Interface Guidelines for iOS compliance.

187 13
Explore
johnrogers/claude-swift-engineering

ios-26-platform

Use when implementing iOS 26 features (Liquid Glass, new SwiftUI APIs, WebView, Chart3D), deploying iOS 26+ apps, or supporting backward compatibility with iOS 17/18.

187 13
Explore
johnrogers/claude-swift-engineering

grdb

Use when writing raw SQL with GRDB, complex joins across 4+ tables, window functions, ValueObservation for reactive queries, or dropping down from SQLiteData for performance. Direct SQLite access for iOS/macOS with type-safe queries and migrations.

187 13
Explore
johnrogers/claude-swift-engineering

swift-testing

Use when writing tests with Swift Testing (@Test,

187 13
Explore
johnrogers/claude-swift-engineering

localization

Use when implementing internationalization (i18n), String Catalogs, pluralization, or right-to-left layout support. Covers modern localization workflows with Xcode String Catalogs and LocalizedStringKey patterns.

187 13
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results