关于 swift-refactor
为开发者提供 Swift 和 SwiftUI 模块化 MVVM-C 重构指南,围绕 Domain、Data、Feature 与 App 的边界组织架构。内容针对 iOS 26 / Swift 6.2,涵盖 API、状态、导航和性能调整。
主要功能
- 01模块化 MVVM-C 包结构指南
- 02SwiftUI API 现代化规则
- 03Observable ViewModel 与状态设计
- 04基于 Coordinator 的导航模式
- 05视图身份与列表性能规则
适用场景
- 01迁移旧版 SwiftUI 导航与状态 API
- 02将应用拆分为 Domain、Data、Feature 和 App 模块
- 03重构视图与列表以改善差异计算
- 04用可取消加载替代手动任务管理
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ pproenca/ dot-skills --skill swift-refactor安装后在 Claude Code 中输入/swift-refactor确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
metadata.jsonassets/templates/_template.mdreferences/_sections.mdapi-alert-confirmation-dialog.mdapi-environment-object-removal.mdapi-list-foreach-identifiable.mdapi-navigationstack-migration.mdapi-observable-macro.mdapi-onchange-signature.mdapi-toolbar-migration.mdarch-environment-key-injection.mdarch-feature-module-extraction.mdarch-model-view-separation.mdarch-protocol-dependencies.mdarch-viewmodel-elimination.mddata-cancellation.mddata-error-loadable.mddata-task-modifier.mddi-container-composition.mddi-mock-testing.mddiff-closure-skip.mddiff-equatable-views.mddiff-identity-stability.mddiff-printchanges-debug.mdlayer-dependency-rule.mdlayer-no-view-repository.mdlayer-repository-protocol.mdlayer-usecase-protocol.mdlayer-viewmodel-boundary.mdlist-constant-viewcount.md详细介绍
Swift/SwiftUI 重构(模块化 MVVM-C)
将 Swift/SwiftUI 代码迁移到模块化 MVVM-C 的全面重构指南,采用本地 SPM 包边界和 App 目标组合根装配。
规定的架构技术栈
┌───────────────────────────────────────────────────────────────┐
│ App target: DependencyContainer, Coordinators, Route Shells │
├───────────────────────────────────────────────────────────────┤
│ Feature modules: View + ViewModel (Domain + DesignSystem deps)│
├───────────────────────────────────────────────────────────────┤
│ Data package: repositories, remote/local stores, sync, retry │
├───────────────────────────────────────────────────────────────┤
│ Domain package: models, repository/coordinator/error protocols │
└───────────────────────────────────────────────────────────────┘
依赖规则:功能模块绝不导入 Data,也绝不导入同级功能模块。
Clinic 架构约定(iOS 26 / Swift 6.2)
本技能中的所有指导均基于 Clinic 模块化 MVVM-C 架构:
- 功能模块仅导入
Domain+DesignSystem(绝不导入Data,也绝不导入同级功能模块) - App 目标是汇聚点,并负责
DependencyContainer、具体协调器和 Route Shell 装配 Domain保持纯 Swift,并定义模型以及 repository、*Coordinating、ErrorRouting和AppError契约Data负责 SwiftData/网络/同步/重试/后台 I/O,并实现 Domain 协议- 读写流程默认采用过期数据优先并后台重新验证的读取方式,以及乐观排队写入
- ViewModel 直接调用 repository 协议(不设默认的用例/交互器层)
适用场景
在以下情况下参考这些指南:
- 从已弃用的 SwiftUI API 迁移(ObservableObject、NavigationView、旧版 onChange)
- 重构状态管理,改用 @Observable ViewModel
- 为视图添加 @Equatable 差分,以提升性能
- 将大型视图拆分为最多包含 10 个节点的视图主体
- 将导航重构为协调器 + Route Shell 模式
- 重构为 Domain/Data/Feature/App 包边界
- 通过
DependencyContainer设置依赖注入 - 提升列表/集合滚动性能
- 用
.task(id:)和可取消加载替代手动 Task 管理
不可协商的约束(iOS 26 / Swift 6.2)
- ViewModel/协调器使用
@Observable,绝不使用ObservableObject/@Published NavigationStack由 App 目标的 Route Shell 和协调器持有- 每个视图都使用
@Equatable宏,绝不使用AnyView - Domain 定义 repository/协调器/错误路由协议;不包含与框架耦合的 I/O
- 不设专用的用例/交互器层;ViewModel 直接调用 repository 协议
- 视图绝不直接访问 repository
按优先级划分的规则类别
| 优先级 | 类别 | 影响 | 前缀 | 规则数 |
|---|---|---|---|---|
| 1 | 视图标识与差分 | 严重 | diff- | 4 |
| 2 | API 现代化 | 严重 | api- | 7 |
| 3 | 状态架构 | 严重 | state- | 6 |
| 4 | 视图组合 | 高 | view- | 7 |
| 5 | 导航与协调 | 高 | nav- | 5 |
| 6 | 分层架构 | 高 | layer- | 5 |
| 7 | 架构模式 | 高 | arch- | 5 |
| 8 | 依赖注入 | 中高 | di- | 2 |
| 9 | 类型安全与协议 | 中高 | type- | 4 |
| 10 | 列表与集合性能 | 中 | list- | 4 |
| 11 | 异步与数据流 | 中 | data- | 3 |
| 12 | Swift 语言基础 | 中 | swift- | 8 |
快速参考
1. 视图标识与差分(严重)
diff-equatable-views- 为每个 SwiftUI 视图添加 @Equatable 宏diff-closure-skip- 对闭包属性使用 @EquatableIgnoreddiff-identity-stability- 在 ForEach 中使用稳定的 O(1) 标识符diff-printchanges-debug- 使用 _printChanges() 诊断重新渲染
2. API 现代化(关键)
api-observable-macro- 将 ObservableObject 迁移到 @Observable 宏api-navigationstack-migration- 用 NavigationStack 替换 NavigationViewapi-onchange-signature- 迁移到新的 onChange 签名api-environment-object-removal- 用 @Environment 替换 @EnvironmentObjectapi-alert-confirmation-dialog- 将 Alert 迁移到 confirmationDialog APIapi-list-foreach-identifiable- 用 Identifiable 一致性替换 id: .selfapi-toolbar-migration- 用 toolbar 修饰符替换 navigationBarItems
3. 状态架构(关键)
state-scope-minimization- 将状态范围缩小到最近的使用者state-derived-over-stored- 使用计算属性,而不是冗余的 @Statestate-binding-extraction- 提取 @Binding,以隔离子视图的重新渲染state-remove-observation- 将 @ObservedObject 迁移到 @Observable 跟踪state-onappear-to-task- 用 .task 修饰符替换 onAppear 闭包state-stateobject-placement- 将 @StateObject 迁移到与 @Observable 搭配使用的 @State
4. 视图组合(高)
view-extract-subviews- 提取子视图,作为差异计算检查点view-eliminate-anyview- 用 @ViewBuilder 或泛型替换 AnyViewview-computed-to-struct- 将计算型视图属性转换为结构体视图view-modifier-extraction- 将重复的修饰符提取到自定义 ViewModifiers 中view-conditional-content- 使用 Group 或条件修饰符,而不是条件视图view-preference-keys- 用 PreferenceKey 替换回调闭包view-body-complexity- 将视图主体最多精简到 10 个节点
5. 导航与协调(高)
nav-centralize-destinations- 将导航重构为协调器模式nav-value-based-links- 用协调器路由替换 NavigationLinknav-path-state-management- 使用 NavigationPath 进行编程式导航nav-split-view-adoption- 使用 NavigationSplitView 实现多列布局nav-sheet-item-pattern- 用项目绑定替换布尔值触发的 sheet
6. 分层架构(高)
layer-dependency-rule- 提取不导入任何框架的领域层layer-usecase-protocol- 移除用例/交互器层;在 ViewModel 和 repository 协议中保留编排逻辑layer-repository-protocol- 在 Domain 中定义 repository 协议,在 Data 中实现layer-no-view-repository- 移除视图对 repository 的直接访问layer-viewmodel-boundary- 重构 ViewModel,使其仅公开可直接显示的状态
7. 架构模式(高)
arch-viewmodel-elimination- 将内联状态重构为 @Observable ViewModelarch-protocol-dependencies- 通过 ViewModel 层提取协议依赖项arch-environment-key-injection- 使用 Environment 键注入服务arch-feature-module-extraction- 将功能提取到独立模块中arch-model-view-separation- 将业务逻辑提取到 Domain 模型和由 repository 支撑的 ViewModel 中
8. 依赖注入(中高)
di-container-composition- 在应用根目录组合依赖容器di-mock-testing- 为每个协议依赖项添加模拟实现
9. 类型安全与协议(中高)
type-tagged-identifiers- 将 String ID 替换为带标签的类型type-result-over-optionals- 使用 Result 类型替代带错误标志的可选值type-phantom-types- 使用虚类型实现编译时状态机type-force-unwrap-elimination- 使用安全替代方案消除强制解包
10. 列表与集合性能(中)
list-constant-viewcount- 确保 ForEach 为每个元素生成固定数量的视图list-filter-in-model- 将筛选/排序逻辑从 ForEach 移至 ViewModellist-lazy-stacks- 对无界内容使用 Lazy 变体替代 VStack/HStacklist-id-keypath- 明确提供 id keyPath — 切勿依赖隐式标识
11. 异步与数据流(中)
data-task-modifier- 使用 .task 修饰符替代 onAppear 中的异步任务data-error-loadable- 使用枚举表示加载状态,而非布尔标志data-cancellation- 使用 .task 自动取消 — 切勿手动管理 Tasks
12. Swift 语言基础(中)
swift-let-vs-var- 常量使用 let,变量使用 varswift-structs-vs-classes- 优先使用结构体而非类swift-camel-case-naming- 使用 camelCase 命名约定swift-string-interpolation- 使用字符串插值处理动态文本swift-functions-clear-names- 清晰地命名函数和参数swift-for-in-loops- 对集合使用 for-in 循环swift-optionals- 通过解包安全处理可选值swift-closures- 使用闭包编写内联函数
使用方法
阅读各参考文件,了解详细说明和代码示例:
参考文件
| 文件 | 描述 |
|---|---|
| references/_sections.md | 类别定义和排序 |
| assets/templates/_template.md | 新规则模板 |
评论
支持 Markdown