SwiftUI architecture guidance for MVVM, Observation, navigation, state ownership, Combine, and UIKit interop. Use when building screens, view models, or routes. Requires swift. Not for iOS SDK APIs or pure Swift language work. Output: architecture and verification guidance.
Scanned 9/2/2026
Install to Claude Code
npx -y skills add hmj1026/dhpk --skill dhpk-swiftui-architecture --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Dhpk Swiftui Architecture?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/hmj1026-dhpk-swiftui-architecture)More formats (shields.io, HTML) on the badges page.
---
name: dhpk-swiftui-architecture
description: 'SwiftUI architecture guidance for MVVM, Observation, navigation, state ownership, Combine, and UIKit interop. Use when building screens, view models, or routes. Requires swift. Not for iOS SDK APIs or pure Swift language work. Output: architecture and verification guidance.'
metadata:
dhpk-invocation-class: implicit-eligible
---
# SwiftUI architecture — MVVM + Coordinator
Load references on demand:
- `references/mvvm-coordinator.md` — layer responsibilities, DI/factory, Coordinator protocol.
- `references/observation-state.md` — `@Observable`/`@Bindable` vs `ObservableObject`, ownership.
- `references/navigation.md` — `NavigationStack`/`NavigationPath`, type-safe routes.
- `references/interop.md` — Combine bridge + `UIViewRepresentable`/`UIHostingController`.
---
## Core rules
1. **Views are thin and declarative.** No business logic, no persistence, no
networking in a `View`. A view reads state from its view model and sends
intents back. Logic that isn't "how to render" belongs in the view model or a
service.
2. **View models are `@Observable @MainActor`.** On the iOS 17 floor prefer the
Observation framework (`@Observable`) over `ObservableObject` + `@Published`.
Don't mix the two paradigms in one type. Inject dependencies (services) via
the initializer behind protocols — never `import`-reach into singletons.
3. **Navigation is owned by a Coordinator, not scattered in views.** A
`NavigationStack` bound to a coordinator-held `NavigationPath`; views append
typed route values, the coordinator maps routes → destination views.
4. **State ownership is explicit.** `@State` for value-typed view-local state;
`@Bindable` for a two-way binding to an `@Observable` model; `@Binding` for
delegated ownership; `@Environment` for ambient dependencies. Owning the same
state in two places is the classic "stale UI" bug.
5. **UIKit/Combine stays behind a boundary.** Wrap `AVCaptureVideoPreviewLayer`,
camera controllers, and the background-blur snapshot in `UIViewRepresentable`/
`UIHostingController`; bridge callback/Combine APIs to `async` or `@Observable`
state at the edge.
## Critical — never
- Never do file/DB/crypto work synchronously in `body` or in a computed view
property — `body` can run many times per frame.
- Never mutate observable state from a background context (see swift module
`concurrency.md`); hop to `@MainActor`.
- Never put `NavigationLink(destination:)` deep-linking logic inline when the app
has more than a couple of screens — route through the coordinator.
- Never retain a view model across identity changes by constructing it inside
`body` (`StateObject`/`@State` owns lifecycle; constructing in `body` recreates
it every render).
## When NOT to Use
- Pure language questions (concurrency, optionals, value vs reference) → swift module.
- iOS SDK frameworks (persistence, crypto, OCR, camera, HealthKit) → ios-platform.
- Test strategy / target structure → swift-test-strategy.
## Output
A SwiftUI screen or layer where views stay declarative, view models are
`@Observable @MainActor` with protocol-injected dependencies, and navigation is
driven by a coordinator-owned `NavigationPath` — plus the correct state-ownership
wrapper (`@State` / `@Binding` / `@Environment` / `@Bindable`) for each piece of state.
## Verification
- [ ] No business logic, persistence, or networking in a `View` or in `body`.
- [ ] View models are `@Observable` (not `ObservableObject` + `@Published`) and `@MainActor`.
- [ ] Routing goes through the coordinator's `NavigationPath`, not inline `NavigationLink(destination:)`.
- [ ] Each state value has exactly one owner; bindings use `@Bindable` / `@Binding`.
- [ ] UIKit / Combine APIs are wrapped at a boundary, not called from `body`.
## babylon mapping
The consent gate, biometric lock gate, and background-masking overlay are
coordinator-driven SwiftUI flows from `app-foundation-compliance` tasks 3–4.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!