Declarative composition, predictable state and safe concurrency. Prefer small views and testable ViewModels when the project uses MVVM. Language: swift. Persistence: swiftdata. IAP: storekit. Widgets: widgetkit. Visual style: better-mobile-interface. i18n: i18n-mobile. Mac platform: macos-development. Watch: watchos-development. iOS deploy: github-actions-ios.
Composition
- Small views, named by purpose.
- Extract subviews and
ViewModifiers instead of giant bodies. - Prefer composition over inheritance.
- Layout containers (
VStack,Grid,Layout) with spacing from the app's design system. - Tests:
swift-testing(Swift Testing + XCUITest).
State
@State— local view state.@Binding— borrowed state.@Observable/ Observation — modern models and ViewModels.@Environment— cross-cutting dependencies (not for every feature state).- Avoid legacy
@ObservedObjectin new code if Observation is available in the deployment target.
Rules:
- Single source of truth.
- Side effects in
.task/.onChangewith cooperative cancellation. - Do not do networking in
body.
Navigation
NavigationStackwith typed value (navigationDestination).- Sheets/fullScreenCover with stable identity.
- Deep links: parse → route state → stack.
- Avoid legacy
NavigationViewin new code.
Concurrency
async/awaitandTaskwith cancellation in.task.@MainActorfor UI state.- Do not block the main thread with I/O.
- Model errors with
throwsand failure states in the UI.
Architecture
- If the app uses MVVM, apply the skill
mvvm-architecture. - Injectable services/repositories for testing.
- Separate networking from the View.
Accessibility and UI polish
- Labels, traits, Dynamic Type.
- Touch targets and contrast.
- Reduce motion when
accessibilityReduceMotion. - SF Symbols with coherent typographic hierarchy.
Previews and performance
- Previews with sample data and states (loading/error/empty).
- Avoid heavy work in
body; useEquatableView/ conscious diffing when needed. - Large lists:
List/LazyVStackappropriate; identify with stableid. - Profile with Instruments if there is jank.
Tests
- ViewModels/services with XCTest.
- UI tests for critical flows.
- Snapshots only if the project already depends on them.
Anti-patterns
- Massive
ContentView - Networking and parsing in
body @Statefor server data without a model layer- Force unwrap in production paths
- Ignoring task cancellation
Completion criteria
- Correct state and concurrency on the MainActor
- Stable typed navigation
- Previews of the main states
- Basic A11y covered
- No unnecessary force unwraps on the happy path/handled error