app-store
App Store optimization and marketing skills for descriptions, screenshots, keywords, review responses, and comprehensive promotional strategy. Use when user…
SwiftUI's actual mental model — view identity, lifetime, and dependencies (the Demystify canon), state ownership decision rules, Observation's per-property tracking, body-performance discipline, and the main-actor concurrency contract. Use when state resets mysteriously, views
$ npx -y skills add rshankras/claude-code-apple-skills --skill data-flow --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/data-flowContext preview
The summary Claude sees to decide when to auto-load this skill.
SwiftUI's actual mental model — view identity, lifetime, and dependencies (the Demystify canon), state ownership decision rules, Observation's per-property tracking, body-performance discipline, and the main-actor concurrency contract. Use when state resets mysteriously, views
name: data-flow description: SwiftUI's actual mental model — view identity, lifetime, and dependencies (the Demystify canon), state ownership decision rules, Observation's per-property tracking, body-performance discipline, and the main-actor concurrency contract. Use when state resets mysteriously, views re-render too often, animations glitch between branches, choosing @State vs @Bindable vs plain property, or debugging "why did body run." allowed-tools: [Read, Write, Edit, Glob, Grep] last_verified: 2026-07-16 review_by: 2027-06-22 os_version: iOS 27 / macOS 27
Nearly every confusing SwiftUI bug — state that resets, animations that crossfade instead of move, lists that flash, bodies that run constantly — traces to identity, lifetime, or dependencies. This is Apple's own mental model (the Demystify sessions + Data Essentials + Observation), current through the WWDC26 `@State` macro.
SwiftUI sees three things: **identity, lifetime, dependencies**. Views with the same identity are "different states of the same conceptual UI element"; distinct identities are distinct views.
identities** (`_ConditionalContent`) — flipping the branch destroys/recreates the view: state resets, transitions crossfade instead of animating.
`ScrollViewReader.scrollTo`). Changing an explicit id is a new identity — new lifetime, fresh state. (That's the `.id(item.id)` force-refresh trick — use it knowingly.)
over branching —
// ❌ two identities; state resets, transition crossfades
if expired { content.opacity(0.3) } else { content }
// ✅ one identity; cheap, pruned when inert
content.opacity(expired ? 0.3 : 1.0)Inert values (opacity 1, padding 0) cost nothing. "By default, try to preserve identity."
struct instance; identity provides continuity.
tears down and reinitializes. If state "randomly resets," find the identity change.
to iOS 17) — the stored object initializes once per lifetime, not on every view-value init. Remove default values when also assigning in `init` (source-breaking edge).
(`0..<n`) only with a constant range.
forces List to resolve every row just to count them. Filter in the **data**, and cache the filtered collection in the model — an inline `.filter` re-runs linearly on every body.
re-run, and value comparison prunes unchanged subtrees. Stable identity is "the backbone of the dependency graph."
model). Extracting subviews is free — "breaking up one view into multiple doesn't hurt performance" — and shrinks invalidation scope.
when a property it actually *read* changes, including through computed properties, arrays, optionals, and nesting.
`@ObservedObject` → delete or `@Bindable`; `@EnvironmentObject` → `@Environment`. Invalidation narrows from whole-object to read-properties — a free performance win.
Ask Apple's three questions: what data does the view need · how does it manipulate it · **where does truth live?**
| Situation | Use | |---|---| | Display-only, parent owns it | plain `let` property | | Transient, view-local UI state | `@State` (group related fields into one struct with mutating methods) | | Write access to someone else's truth | `@Binding` (bindings compose: `$config.note`) | | Observable model owned by this view | `@State` (lazy-init since WWDC26 macro) | | Observable model, needs `$model.field` bindings only | `@Bindable` | | Observable model, globally available | `@Environment` | | Observable model, none of the above | plain property |
re-run reallocates it (heap churn, data loss); use `@StateObject` or `@State` + `@Observable`.
and hand children Bindings.
*
A collection of Claude Code skills for iOS, macOS, watchOS, visionOS, and Apple platform development. These skills help you plan and build apps, maintain code quality, ensure HIG compliance, and guide you from idea to App Store.
Repo: rshankras/claude-code-apple-skills
App Store optimization and marketing skills for descriptions, screenshots, keywords, review responses, and comprehensive promotional strategy. Use when user…
Privacy-preserving ad measurement with AdAttributionKit (SKAdNetwork's successor) — install and re-engagement attribution, conversion-value strategy under…
Generate compelling App Store descriptions that convert browsers into users. Use when writing initial descriptions, improving existing copy, or drafting…
Apple Search Ads campaign strategy for indie developers — paid acquisition, keyword bidding, budget planning, and ROAS optimization. Use when user asks about…
Take a one-time in-app purchase from MISSING_METADATA to READY_TO_SUBMIT in App Store Connect — set its price schedule and localized display name/description…
Optimize app title, subtitle, and keywords for maximum App Store discoverability. Use when launching a new app, improving search rankings, entering new…