名称:swift-ui-architect
描述:针对 iOS 26 / Swift 6.2 诊所式模块化 MVVM-C 应用,使用本地 SPM 包边界实施观点鲜明的 SwiftUI 架构。强制执行 App 目标中的 DependencyContainer + 路由外壳、@Observable ViewModels/协调器、Domain 仓库/协调器/错误路由协议、数据拥有的 I/O、陈旧数据重新验证读取和乐观排队同步。适用于编写、审查或重构 SwiftUI 架构、导航、依赖注入或仓库边界时使用。
SwiftUI 模块化 MVVM-C 架构
针对 SwiftUI 诊所式应用的观点鲜明架构实施。此技能与 iOS 26 / Swift 6.2 诊所架构对齐:在本地 SPM 包中的模块化 MVVM-C、App 目标中的具体协调器和路由外壳、纯 Domain 协议,以及 Data 作为唯一的 I/O 层。
强制架构栈
┌───────────────────────────────────────────────────────────────┐
│ App 目标:DependencyContainer、协调器、路由外壳 │
├───────────────┬───────────────┬───────────────┬──────────────┤
│ 功能* SPM │ 功能* SPM │ 功能* SPM │ 功能* SPM │
│ 视图 + 视图模型 │ 视图 + 视图模型 │ 视图 + 视图模型 │ 视图 + 视图模型 │
├───────────────────────────────────────────────────────────────┤
│ Data SPM:仓库实现、远程/本地、重试、同步队列 │
├───────────────────────────────────────────────────────────────┤
│ Domain SPM:模型、仓库协议、协调器协议、错误路由/AppError │
├───────────────────────────────────────────────────────────────┤
│ 共享 SPMs:DesignSystem、SharedKit │
└───────────────────────────────────────────────────────────────┘
依赖规则:功能模块仅导入 Domain + DesignSystem。功能从不导入 Data 或其他功能。App 目标是唯一的汇合点。
诊所架构合约 (iOS 26 / Swift 6.2)
本技能中的所有指导均假设诊所模块化 MVVM-C 架构:
- 功能模块仅导入
Domain+DesignSystem(从不导入Data,从不导入兄弟功能) - App 目标是汇合点,拥有
DependencyContainer、具体协调器和路由外壳接线 Domain保持纯 Swift,定义模型以及仓库、*Coordinating、ErrorRouting和AppError合约Data拥有 SwiftData/网络/同步/重试/后台 I/O 并实现 Domain 协议- 读写流默认使用陈旧数据重新验证读取和乐观排队写入
- 视图模型直接调用仓库协议(无默认用例/交互层)
何时应用
参考这些指南:
- 构建或重构本地 SPM 包下的功能模块
- 接线协调器、路由外壳和依赖容器工厂
- 定义仓库、协调器和错误路由的 Domain 协议
- 强制执行仅 Data 拥有网络、持久化和同步
- 审查陈旧数据重新验证读取和乐观排队写入
非协商约束 (iOS 26 / Swift 6.2)
- 视图模型/协调器使用
@Observable,从不使用ObservableObject/@Published - 无专用用例/交互层:视图模型直接调用 Domain 仓库协议
- 协调器协议位于 Domain;具体协调器在 App 目标中拥有
NavigationPath - 路由外壳位于 App 目标,拥有
.navigationDestination映射 AppError+ErrorRouting驱动展示策略;视图模型不硬编码全局错误 UI- SwiftData / URLSession / 重试 / 同步队列逻辑仅保留在 Data 包中
按优先级分类的规则类别
| 优先级 | 类别 | 影响 | 前缀 | 规则数 |
|---|---|---|---|---|
| 1 | 视图身份与差异 | 关键 | diff- |
6 |
| 2 | 状态架构 | 关键 | state- |
7 |
| 3 | 视图组合 | 高 | view- |
6 |
| 4 | 导航与协调 | 高 | nav- |
5 |
| 5 | 层架构 | 高 | layer- |
6 |
| 6 | 依赖注入 | 中高 | di- |
4 |
| 7 | 列表与集合性能 | 中 | list- |
4 |
| 8 | 异步与数据流 | 中 | data- |
5 |
快速参考
1. 视图身份与差异 (关键)
diff-equatable-views- 对每个 SwiftUI 视图应用 @Equatable 宏diff-closure-skip- 对闭包/处理器属性使用 @SkipEquatablediff-reference-types- 从不存储无 Equatable 一致性的引用类型diff-identity-stability- 在 ForEach 中使用稳定 O(1) 标识符diff-avoid-anyview- 从不使用 AnyView — 使用 @ViewBuilder 或泛型diff-printchanges-debug- 使用 _printChanges() 诊断不必要的重新渲染
2. 状态架构 (关键)
state-observable-class- 对所有视图模型使用 @Observable 类state-ownership- @State 用于自有数据,普通属性用于注入数据state-single-source- 每个状态只有一个真理源state-scoped-observation- 利用 @Observable 属性级跟踪state-binding-minimal- 仅双向数据流时传递 @Bindingstate-environment-global- 使用 @Environment 用于应用范围的共享依赖state-no-published- 从不使用 @Published 或 ObservableObject
3. 视图组合 (高)
view-body-complexity- 视图体中最多 10 个节点view-extract-subviews- 将计算属性/助手提取到单独的 View 结构view-no-logic-in-body- 体中零业务逻辑view-minimal-dependencies- 仅传递所需属性,非整个模型view-viewbuilder-composition- 使用 @ViewBuilder 进行条件组合view-no-init-sideeffects- 从不在 View init 中执行工作
4. 导航与协调 (高)
nav-coordinator-pattern- 每个功能有一个拥有 NavigationStack 的协调器nav-routes-enum- 定义所有路由为 Hashable 枚举nav-deeplink-support- 协调器必须支持基于 URL 的深层链接nav-modal-sheets- 通过协调器呈现模态,非内联nav-no-navigationlink- 从不使用 NavigationLink(destination:) — 使用 navigationDestination(for:)
5. 层架构 (高)
layer-dependency-rule- Domain 层零框架导入layer-usecase-protocol- 不添加用例层;编排保留在视图模型 + 仓库协议中layer-repository-protocol- 仓库协议在 Domain,实现在 Datalayer-model-value-types- Domain 模型是结构体,从不使用类layer-no-view-repository- 视图从不直接访问仓库;视图模型调用仓库协议layer-viewmodel-boundary- 视图模型仅暴露准备显示的状態
6. 依赖注入 (中高)
di-environment-injection- 通过 @Environment 注入容器管理的协议依赖di-protocol-abstraction- 所有注入依赖都是协议类型di-container-composition- 在 App 目标中组合DependencyContainer并暴露 VM 工厂di-mock-testing- 每个协议依赖都有用于测试的模拟
7. 列表与集合性能 (中)
list-constant-viewcount- ForEach 必须为每个元素产生恒定的视图数list-filter-in-model- 在视图模型中过滤/排序,从不内联 ForEachlist-lazy-stacks- 对无界内容使用 LazyVStack/LazyHStacklist-id-keypath- 提供显式 id keyPath — 从不依赖隐式身份
8. 异步与数据流 (中)
data-task-modifier- 使用.task(id:)作为主要功能数据加载触发器data-async-init- 从不在 init 中执行异步工作data-error-loadable- 建模加载状态为枚举,非布尔值data-combine-avoid- 新代码优先选择 async/await,而非 Combinedata-cancellation- 使用 .task 自动取消 — 从不手动管理 Tasks
如何使用
阅读单个参考文件获取详细解释和代码示例:
参考文件
| 文件 | 描述 |
|---|---|
| references/_sections.md | 类别定义和排序 |
| assets/templates/_template.md | 新规则模板 |
| metadata.json | 版本和参考信息 |