swift-refactor
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSwift/SwiftUI Refactor (Modular MVVM-C)
Swift/SwiftUI 重构(模块化MVVM-C)
Comprehensive refactoring guide for migrating Swift/SwiftUI code to modular MVVM-C with local SPM package boundaries and App-target composition root wiring.
将Swift/SwiftUI代码迁移至带有本地SPM包边界和应用目标组合根配置的模块化MVVM-C架构的全面重构指南。
Mandated Architecture Stack
强制要求的架构栈
┌───────────────────────────────────────────────────────────────┐
│ 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 │
└───────────────────────────────────────────────────────────────┘Dependency Rule: Feature modules never import and never import sibling features.
Data┌───────────────────────────────────────────────────────────────┐
│ 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 │
└───────────────────────────────────────────────────────────────┘依赖规则:功能模块绝不能导入包,也不能导入同级功能模块。
DataClinic Architecture Contract (iOS 26 / Swift 6.2)
诊所式架构规范(iOS 26 / Swift 6.2)
All guidance in this skill assumes the clinic modular MVVM-C architecture:
- Feature modules import +
Domainonly (neverDesignSystem, never sibling features)Data - App target is the convergence point and owns , concrete coordinators, and Route Shell wiring
DependencyContainer - stays pure Swift and defines models plus repository,
Domain,*Coordinating, andErrorRoutingcontractsAppError - owns SwiftData/network/sync/retry/background I/O and implements Domain protocols
Data - Read/write flow defaults to stale-while-revalidate reads and optimistic queued writes
- ViewModels call repository protocols directly (no default use-case/interactor layer)
本技能中的所有指导均基于诊所式模块化MVVM-C架构:
- 功能模块仅导入和
Domain(绝不导入DesignSystem,也不导入同级功能模块)Data - App目标是聚合点,负责、具体协调器和路由外壳的配置
DependencyContainer - 保持纯Swift实现,定义模型以及仓库、
Domain、*Coordinating和ErrorRouting协议AppError - 层负责SwiftData/网络/同步/重试/后台I/O操作,并实现Domain层定义的协议
Data - 读写流程默认采用stale-while-revalidate读取机制和乐观队列写入机制
- ViewModels直接调用仓库协议(无默认用例/交互器层)
When to Apply
适用场景
Reference these guidelines when:
- Migrating from deprecated SwiftUI APIs (ObservableObject, NavigationView, old onChange)
- Restructuring state management to use @Observable ViewModels
- Adding @Equatable diffing to views for performance
- Decomposing large views into 10-node maximum bodies
- Refactoring navigation to coordinator + route shell pattern
- Refactoring to Domain/Data/Feature/App package boundaries
- Setting up dependency injection through
DependencyContainer - Improving list/collection scroll performance
- Replacing manual Task management with and cancellable loading
.task(id:)
在以下场景中参考本指南:
- 从已废弃的SwiftUI API(ObservableObject、NavigationView、旧版onChange)迁移
- 重构状态管理以使用@Observable ViewModels
- 为视图添加@Equatable diffing以提升性能
- 将大型视图分解为最多包含10个节点的视图体
- 将导航重构为协调器+路由外壳模式
- 重构为Domain/Data/Feature/App包边界
- 通过设置依赖注入
DependencyContainer - 提升列表/集合的滚动性能
- 使用和可取消加载替代手动Task管理
.task(id:)
Non-Negotiable Constraints (iOS 26 / Swift 6.2)
不可协商的约束(iOS 26 / Swift 6.2)
- ViewModels/coordinators,
@Observable/ObservableObjectnever@Published - is owned by App-target route shells and coordinators
NavigationStack - macro on every view,
@EquatableneverAnyView - Domain defines repository/coordinator/error-routing protocols; no framework-coupled I/O
- No dedicated use-case/interactor layer; ViewModels call repository protocols directly
- Views never access repositories directly
- 必须使用ViewModels/协调器,绝不使用
@Observable/ObservableObject@Published - 由App目标的路由外壳和协调器管理
NavigationStack - 每个视图都必须添加宏,绝不使用
@EquatableAnyView - Domain层定义仓库/协调器/错误路由协议;不允许与框架耦合的I/O操作
- 无专用用例/交互器层;ViewModels直接调用仓库协议
- 视图绝不能直接访问仓库
Rule Categories by Priority
按优先级划分的规则类别
| Priority | Category | Impact | Prefix | Rules |
|---|---|---|---|---|
| 1 | View Identity & Diffing | CRITICAL | | 4 |
| 2 | API Modernization | CRITICAL | | 7 |
| 3 | State Architecture | CRITICAL | | 6 |
| 4 | View Composition | HIGH | | 7 |
| 5 | Navigation & Coordination | HIGH | | 5 |
| 6 | Layer Architecture | HIGH | | 5 |
| 7 | Architecture Patterns | HIGH | | 5 |
| 8 | Dependency Injection | MEDIUM-HIGH | | 2 |
| 9 | Type Safety & Protocols | MEDIUM-HIGH | | 4 |
| 10 | List & Collection Performance | MEDIUM | | 4 |
| 11 | Async & Data Flow | MEDIUM | | 3 |
| 12 | Swift Language Fundamentals | MEDIUM | | 8 |
| 优先级 | 类别 | 影响级别 | 前缀 | 规则数量 |
|---|---|---|---|---|
| 1 | 视图标识与Diffing | 关键 | | 4 |
| 2 | API现代化 | 关键 | | 7 |
| 3 | 状态架构 | 关键 | | 6 |
| 4 | 视图组合 | 高 | | 7 |
| 5 | 导航与协调 | 高 | | 5 |
| 6 | 分层架构 | 高 | | 5 |
| 7 | 架构模式 | 高 | | 5 |
| 8 | 依赖注入 | 中高 | | 2 |
| 9 | 类型安全与协议 | 中高 | | 4 |
| 10 | 列表与集合性能 | 中 | | 4 |
| 11 | 异步与数据流 | 中 | | 3 |
| 12 | Swift语言基础 | 中 | | 8 |
Quick Reference
快速参考
1. View Identity & Diffing (CRITICAL)
1. 视图标识与Diffing(关键)
- - Add @Equatable macro to every SwiftUI view
diff-equatable-views - - Use @EquatableIgnored for closure properties
diff-closure-skip - - Use stable O(1) identifiers in ForEach
diff-identity-stability - - Use _printChanges() to diagnose re-renders
diff-printchanges-debug
- - 为每个SwiftUI视图添加@Equatable宏
diff-equatable-views - - 对闭包属性使用@EquatableIgnored
diff-closure-skip - - 在ForEach中使用稳定的O(1)标识符
diff-identity-stability - - 使用_printChanges()诊断重渲染问题
diff-printchanges-debug
2. API Modernization (CRITICAL)
2. API现代化(关键)
- - Migrate ObservableObject to @Observable macro
api-observable-macro - - Replace NavigationView with NavigationStack
api-navigationstack-migration - - Migrate to new onChange signature
api-onchange-signature - - Replace @EnvironmentObject with @Environment
api-environment-object-removal - - Migrate Alert to confirmationDialog API
api-alert-confirmation-dialog - - Replace id: .self with Identifiable conformance
api-list-foreach-identifiable - - Replace navigationBarItems with toolbar modifier
api-toolbar-migration
- - 将ObservableObject迁移至@Observable宏
api-observable-macro - - 用NavigationStack替代NavigationView
api-navigationstack-migration - - 迁移至新版onChange签名
api-onchange-signature - - 用@Environment替代@EnvironmentObject
api-environment-object-removal - - 将Alert迁移至confirmationDialog API
api-alert-confirmation-dialog - - 用Identifiable协议替代id: .self
api-list-foreach-identifiable - - 用toolbar修饰符替代navigationBarItems
api-toolbar-migration
3. State Architecture (CRITICAL)
3. 状态架构(关键)
- - Minimize state scope to nearest consumer
state-scope-minimization - - Use computed properties over redundant @State
state-derived-over-stored - - Extract @Binding to isolate child re-renders
state-binding-extraction - - Migrate @ObservedObject to @Observable tracking
state-remove-observation - - Replace onAppear closures with .task modifier
state-onappear-to-task - - Migrate @StateObject to @State with @Observable
state-stateobject-placement
- - 将状态范围最小化至最近的消费者
state-scope-minimization - - 使用计算属性替代冗余的@State
state-derived-over-stored - - 提取@Binding以隔离子视图重渲染
state-binding-extraction - - 将@ObservedObject迁移至@Observable追踪
state-remove-observation - - 用.task修饰符替代onAppear闭包
state-onappear-to-task - - 将@StateObject迁移至带@Observable的@State
state-stateobject-placement
4. View Composition (HIGH)
4. 视图组合(高)
- - Extract subviews for diffing checkpoints
view-extract-subviews - - Replace AnyView with @ViewBuilder or generics
view-eliminate-anyview - - Convert computed view properties to struct views
view-computed-to-struct - - Extract repeated modifiers into custom ViewModifiers
view-modifier-extraction - - Use Group or conditional modifiers over conditional views
view-conditional-content - - Replace callback closures with PreferenceKey
view-preference-keys - - Reduce view body to maximum 10 nodes
view-body-complexity
- - 提取子视图作为diffing检查点
view-extract-subviews - - 用@ViewBuilder或泛型替代AnyView
view-eliminate-anyview - - 将计算型视图属性转换为结构体视图
view-computed-to-struct - - 将重复的修饰符提取为自定义ViewModifiers
view-modifier-extraction - - 用Group或条件修饰符替代条件视图
view-conditional-content - - 用PreferenceKey替代回调闭包
view-preference-keys - - 将视图体复杂度降低至最多10个节点
view-body-complexity
5. Navigation & Coordination (HIGH)
5. 导航与协调(高)
- - Refactor navigation to coordinator pattern
nav-centralize-destinations - - Replace NavigationLink with coordinator routes
nav-value-based-links - - Use NavigationPath for programmatic navigation
nav-path-state-management - - Use NavigationSplitView for multi-column layouts
nav-split-view-adoption - - Replace boolean sheet triggers with item binding
nav-sheet-item-pattern
- - 将导航重构为协调器模式
nav-centralize-destinations - - 用协调器路由替代NavigationLink
nav-value-based-links - - 使用NavigationPath实现程序化导航
nav-path-state-management - - 对多列布局使用NavigationSplitView
nav-split-view-adoption - - 用item绑定替代布尔值弹窗触发器
nav-sheet-item-pattern
6. Layer Architecture (HIGH)
6. 分层架构(高)
- - Extract domain layer with zero framework imports
layer-dependency-rule - - Remove use-case/interactor layer; keep orchestration in ViewModel + repository protocols
layer-usecase-protocol - - Repository protocols in Domain, implementations in Data
layer-repository-protocol - - Remove direct repository access from views
layer-no-view-repository - - Refactor ViewModels to expose display-ready state only
layer-viewmodel-boundary
- - 提取零框架依赖的领域层
layer-dependency-rule - - 移除用例/交互器层;将编排逻辑保留在ViewModel+仓库协议中
layer-usecase-protocol - - 仓库协议定义在Domain层,实现放在Data层
layer-repository-protocol - - 移除视图对仓库的直接访问
layer-no-view-repository - - 重构ViewModels使其仅暴露可直接用于展示的状态
layer-viewmodel-boundary
7. Architecture Patterns (HIGH)
7. 架构模式(高)
- - Restructure inline state into @Observable ViewModel
arch-viewmodel-elimination - - Extract protocol dependencies through ViewModel layer
arch-protocol-dependencies - - Use Environment keys for service injection
arch-environment-key-injection - - Extract features into independent modules
arch-feature-module-extraction - - Extract business logic into Domain models and repository-backed ViewModels
arch-model-view-separation
- - 将内联状态重构为@Observable ViewModel
arch-viewmodel-elimination - - 通过ViewModel层提取协议依赖
arch-protocol-dependencies - - 使用Environment键实现服务注入
arch-environment-key-injection - - 将功能提取为独立模块
arch-feature-module-extraction - - 将业务逻辑提取至Domain模型和仓库驱动的ViewModels
arch-model-view-separation
8. Dependency Injection (MEDIUM-HIGH)
8. 依赖注入(中高)
- - Compose dependency container at app root
di-container-composition - - Add mock implementation for every protocol dependency
di-mock-testing
- - 在应用根节点组合依赖容器
di-container-composition - - 为每个协议依赖添加Mock实现
di-mock-testing
9. Type Safety & Protocols (MEDIUM-HIGH)
9. 类型安全与协议(中高)
- - Replace String IDs with tagged types
type-tagged-identifiers - - Use Result type over optional with error flag
type-result-over-optionals - - Use phantom types for compile-time state machines
type-phantom-types - - Eliminate force unwraps with safe alternatives
type-force-unwrap-elimination
- - 用标记类型替代String类型的ID
type-tagged-identifiers - - 使用Result类型替代带错误标记的可选值
type-result-over-optionals - - 使用幽灵类型实现编译时状态机
type-phantom-types - - 使用安全替代方案消除强制解包
type-force-unwrap-elimination
10. List & Collection Performance (MEDIUM)
10. 列表与集合性能(中)
- - Ensure ForEach produces constant view count per element
list-constant-viewcount - - Move filter/sort logic from ForEach into ViewModel
list-filter-in-model - - Replace VStack/HStack with Lazy variants for unbounded content
list-lazy-stacks - - Provide explicit id keyPath — never rely on implicit identity
list-id-keypath
- - 确保ForEach为每个元素生成固定数量的视图
list-constant-viewcount - - 将过滤/排序逻辑从ForEach移至ViewModel
list-filter-in-model - - 对无界内容用Lazy变体替代VStack/HStack
list-lazy-stacks - - 提供显式的id键路径——绝不依赖隐式标识
list-id-keypath
11. Async & Data Flow (MEDIUM)
11. 异步与数据流(中)
- - Replace onAppear async work with .task modifier
data-task-modifier - - Model loading states as enum instead of boolean flags
data-error-loadable - - Use .task automatic cancellation — never manage Tasks manually
data-cancellation
- - 用.task修饰符替代onAppear中的异步操作
data-task-modifier - - 用枚举建模加载状态,替代布尔标记
data-error-loadable - - 使用.task自动取消——绝不手动管理Tasks
data-cancellation
12. Swift Language Fundamentals (MEDIUM)
12. Swift语言基础(中)
- - Use let for constants, var for variables
swift-let-vs-var - - Prefer structs over classes
swift-structs-vs-classes - - Use camelCase naming convention
swift-camel-case-naming - - Use string interpolation for dynamic text
swift-string-interpolation - - Name functions and parameters for clarity
swift-functions-clear-names - - Use for-in loops for collections
swift-for-in-loops - - Handle optionals safely with unwrapping
swift-optionals - - Use closures for inline functions
swift-closures
- - 用let定义常量,var定义变量
swift-let-vs-var - - 优先使用结构体而非类
swift-structs-vs-classes - - 使用驼峰命名法
swift-camel-case-naming - - 使用字符串插值处理动态文本
swift-string-interpolation - - 为函数和参数命名时保证清晰性
swift-functions-clear-names - - 对集合使用for-in循环
swift-for-in-loops - - 安全处理可选值的解包
swift-optionals - - 使用闭包实现内联函数
swift-closures
How to Use
使用方法
Read individual reference files for detailed explanations and code examples:
- Section definitions - Category structure and impact levels
- Rule template - Template for adding new rules
阅读单个参考文件获取详细说明和代码示例:
- 章节定义 - 类别结构和影响级别
- 规则模板 - 添加新规则的模板
Reference Files
参考文件
| File | Description |
|---|---|
| references/_sections.md | Category definitions and ordering |
| assets/templates/_template.md | Template for new rules |
| 文件 | 描述 |
|---|---|
| references/_sections.md | 类别定义与排序 |
| assets/templates/_template.md | 新规则模板 |