Install any skill in seconds. Free to start, no credit card required.
Get Started Free →rshankras/data-flow
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.
Passed 20 of 22 test cases with the skill, and 18 of 22 without it.
2 fixed18 passed either way2 still failing0 broke
Tokens, turns and time describe resource use, not a dollar price.
One of 2 test cases the skill fixed. Same model, same prompt, with and without the skill.
When a user taps a purchase button, an async network call runs via 'Task { await processPayment() }', and internal loading state is set to true on the line right after 'await'. Users report UI lag before the spinner appears. How should the state update be ordered?
| Checked | Without skill | With skill |
|---|---|---|
| Explains that awaiting before state mutation defers state changes across frame boundaries | Missed | Passed |
| Recommends mutating state synchronously before initiating the asynchronous work | Passed | Passed |
The instructions your model reads when the skill loads.
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.
ForEach misbehaving@State, @Binding, @Bindable, @Environment, plain propertySelf._printChanges(); concurrency warnings in view codeSwiftUI 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.
Structural identity = type + position in the hierarchy. An if/else creates two
identities (_ConditionalContent) — flipping the branch destroys/recreates the view: state
resets, transitions crossfade instead of animating.
Explicit identity = id: in ForEach or .id(_:) (also the target for
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.)
The inert-modifier rule (the most under-used fix): prefer one view whose modifiers vary 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."
Conditionally include a view inside a stack rather than conditionally wrapping the stack.
test cases passed, vs 18 / 22 without
More skills from the same source and nearby in the registry, with their headline benchmark lift.