← Build iOS AppsCONTENT HISTORY

Update to Build iOS Apps

Snapshot Sep 30, 2026 · 23:18 UTC · version 0.1.2

Collection source: not recorded for this historical snapshot.

WHAT CHANGED · RULE-BASED ANALYSIS

First saved snapshot

No earlier snapshot is available to establish a change.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "name": "swiftui-ui-patterns",
  "description": "Build and refactor SwiftUI UI with component patterns and examples. Use when shaping navigation, state, layouts, controls, or screen composition.",
  "included_files": [
    {
      "relative_path": "agents/openai.yaml",
      "size_in_bytes": 221
    },
    {
      "relative_path": "references/app-wiring.md",
      "size_in_bytes": 6637
    },
    {
      "relative_path": "references/async-state.md",
      "size_in_bytes": 2833
    },
    {
      "relative_path": "references/components-index.md",
      "size_in_bytes": 4303
    },
    {
      "relative_path": "references/controls.md",
      "size_in_bytes": 1682
    },
    {
      "relative_path": "references/deeplinks.md",
      "size_in_bytes": 1703
    },
    {
      "relative_path": "references/focus.md",
      "size_in_bytes": 2390
    },
    {
      "relative_path": "references/form.md",
      "size_in_bytes": 3062
    },
    {
      "relative_path": "references/grids.md",
      "size_in_bytes": 1851
    },
    {
      "relative_path": "references/haptics.md",
      "size_in_bytes": 2049
    },
    {
      "relative_path": "references/input-toolbar.md",
      "size_in_bytes": 1451
    },
    {
      "relative_path": "references/lightweight-clients.md",
      "size_in_bytes": 2524
    },
    {
      "relative_path": "references/list.md",
      "size_in_bytes": 2732
    },
    {
      "relative_path": "references/loading-placeholders.md",
      "size_in_bytes": 1274
    },
    {
      "relative_path": "references/macos-settings.md",
      "size_in_bytes": 1997
    },
    {
      "relative_path": "references/matched-transitions.md",
      "size_in_bytes": 1674
    },
    {
      "relative_path": "references/media.md",
      "size_in_bytes": 2040
    },
    {
      "relative_path": "references/menu-bar.md",
      "size_in_bytes": 2236
    },
    {
      "relative_path": "references/navigationstack.md",
      "size_in_bytes": 4343
    },
    {
      "relative_path": "references/overlay.md",
      "size_in_bytes": 1238
    },
    {
      "relative_path": "references/performance.md",
      "size_in_bytes": 1990
    },
    {
      "relative_path": "references/previews.md",
      "size_in_bytes": 1688
    },
    {
      "relative_path": "references/scroll-reveal.md",
      "size_in_bytes": 5299
    },
    {
      "relative_path": "references/scrollview.md",
      "size_in_bytes": 2364
    },
    {
      "relative_path": "references/searchable.md",
      "size_in_bytes": 1727
    },
    {
      "relative_path": "references/sheets.md",
      "size_in_bytes": 4272
    },
    {
      "relative_path": "references/split-views.md",
      "size_in_bytes": 2027
    },
    {
      "relative_path": "references/tabview.md",
      "size_in_bytes": 3486
    },
    {
      "relative_path": "references/theming.md",
      "size_in_bytes": 1776
    },
    {
      "relative_path": "references/title-menus.md",
      "size_in_bytes": 2115
    },
    {
      "relative_path": "references/top-bar.md",
      "size_in_bytes": 1359
    }
  ],
  "skill_md_contents": "---\nname: swiftui-ui-patterns\ndescription: Build and refactor SwiftUI UI with component patterns and examples. Use when shaping navigation, state, layouts, controls, or screen composition.\n---\n\n# SwiftUI UI Patterns\n\n## Quick start\n\nChoose a track based on your goal:\n\n### Existing project\n\n- Identify the feature or screen and the primary interaction model (list, detail, editor, settings, tabbed).\n- Find a nearby example in the repo with `rg \"TabView\\(\"` or similar, then read the closest SwiftUI view.\n- Apply local conventions: prefer SwiftUI-native state, keep state local when possible, and use environment injection for shared dependencies.\n- Choose the relevant component reference from `references/components-index.md` and follow its guidance.\n- If the interaction reveals secondary content by dragging or scrolling the primary content away, read `references/scroll-reveal.md` before implementing gestures manually.\n- Build the view with small, focused subviews and SwiftUI-native data flow.\n\n### New project scaffolding\n\n- Start with `references/app-wiring.md` to wire TabView + NavigationStack + sheets.\n- Add a minimal `AppTab` and `RouterPath` based on the provided skeletons.\n- Choose the next component reference based on the UI you need first (TabView, NavigationStack, Sheets).\n- Expand the route and sheet enums as new screens are added.\n\n## General rules to follow\n\n- Use modern SwiftUI state (`@State`, `@Binding`, `@Observable`, `@Environment`) and avoid unnecessary view models.\n- If the deployment target includes iOS 16 or earlier and cannot use the Observation API introduced in iOS 17, fall back to `ObservableObject` with `@StateObject` for root ownership, `@ObservedObject` for injected observation, and `@EnvironmentObject` only for truly shared app-level state.\n- Prefer composition; keep views small and focused.\n- Use async/await with `.task` and explicit loading/error states. For restart, cancellation, and debouncing guidance, read `references/async-state.md`.\n- Keep shared app services in `@Environment`, but prefer explicit initializer injection for feature-local dependencies and models. For root wiring patterns, read `references/app-wiring.md`.\n- Prefer the newest SwiftUI API that fits the deployment target and call out the minimum OS whenever a pattern depends on it.\n- Maintain existing legacy patterns only when editing legacy files.\n- Follow the project's formatter and style guide.\n- **Sheets**: Prefer `.sheet(item:)` over `.sheet(isPresented:)` when state represents a selected model. Avoid `if let` inside a sheet body. Sheets should own their actions and call `dismiss()` internally instead of forwarding `onCancel`/`onConfirm` closures.\n- **Scroll-driven reveals**: Prefer deriving a normalized progress value from scroll offset and driving the visual state from that single source of truth. Avoid parallel gesture state machines unless scroll alone cannot express the interaction.\n\n## State ownership summary\n\nUse the narrowest state tool that matches the ownership model:\n\n| Scenario | Preferred pattern |\n| --- | --- |\n| Local UI state owned by one view | `@State` |\n| Child mutates parent-owned value state | `@Binding` |\n| Root-owned reference model on iOS 17+ | `@State` with an `@Observable` type |\n| Child reads or mutates an injected `@Observable` model on iOS 17+ | Pass it explicitly as a stored property |\n| Shared app service or configuration | `@Environment(Type.self)` |\n| Legacy reference model on iOS 16 and earlier | `@StateObject` at the root, `@ObservedObject` when injected |\n\nChoose the ownership location first, then pick the wrapper. Do not introduce a reference model when plain value state is enough.\n\n## Cross-cutting references\n\n- In addition to the references below, use web search to consult current Apple Developer documentation when SwiftUI APIs, availability, or platform guidance may have changed.\n- `references/navigationstack.md`: navigation ownership, per-tab history, and enum routing.\n- `references/sheets.md`: centralized modal presentation and enum-driven sheets.\n- `references/deeplinks.md`: URL handling and routing external links into app destinations.\n- `references/app-wiring.md`: root dependency graph, environment usage, and app shell wiring.\n- `references/async-state.md`: `.task`, `.task(id:)`, cancellation, debouncing, and async UI state.\n- `references/previews.md`: `#Preview`, fixtures, mock environments, and isolated preview setup.\n- `references/performance.md`: stable identity, observation scope, lazy containers, and render-cost guardrails.\n\n## Anti-patterns\n\n- Giant views that mix layout, business logic, networking, routing, and formatting in one file.\n- Multiple boolean flags for mutually exclusive sheets, alerts, or navigation destinations.\n- Live service calls directly inside `body`-driven code paths instead of view lifecycle hooks or injected models/services.\n- Reaching for `AnyView` to work around type mismatches that should be solved with better composition.\n- Defaulting every shared dependency to `@EnvironmentObject` or a global router without a clear ownership reason.\n\n## Workflow for a new SwiftUI view\n\n1. Define the view's state, ownership location, and minimum OS assumptions before writing UI code.\n2. Identify which dependencies belong in `@Environment` and which should stay as explicit initializer inputs.\n3. Sketch the view hierarchy, routing model, and presentation points; extract repeated parts into subviews. For complex navigation, read `references/navigationstack.md`, `references/sheets.md`, or `references/deeplinks.md`. **Build and verify no compiler errors before proceeding.**\n4. Implement async loading with `.task` or `.task(id:)`, plus explicit loading and error states when needed. Read `references/async-state.md` when the work depends on changing inputs or cancellation.\n5. Add previews for the primary and secondary states, then add accessibility labels or identifiers when the UI is interactive. Read `references/previews.md` when the view needs fixtures or injected mock dependencies.\n6. Validate with a build: confirm no compiler errors, check that previews render without crashing, ensure state changes propagate correctly, and sanity-check that list identity and observation scope will not cause avoidable re-renders. Read `references/performance.md` if the screen is large, scroll-heavy, or frequently updated. For common SwiftUI compilation errors — missing `@State` annotations, ambiguous `ViewBuilder` closures, or mismatched generic types — resolve them before updating callsites. **If the build fails:** read the error message carefully, fix the identified issue, then rebuild before proceeding to the next step. If a preview crashes, isolate the offending subview, confirm its state initialisation is valid, and re-run the preview before continuing.\n\n## Component references\n\nUse `references/components-index.md` as the entry point. Each component reference should include:\n- Intent and best-fit scenarios.\n- Minimal usage pattern with local conventions.\n- Pitfalls and performance notes.\n- Paths to existing examples in the current repo.\n\n## Adding a new component reference\n\n- Create `references/<component>.md`.\n- Keep it short and actionable; link to concrete files in the current repo.\n- Update `references/components-index.md` with the new entry.\n"
}

SHA-256: 1ee1b643a4b393efaed4f7c5d04360831b00c6cc5a323ec961c1197625cd60c3