重要前提
安装AI Skills的关键前提是:必须科学上网,且开启TUN模式,这一点至关重要,直接决定安装能否顺利完成,在此郑重提醒三遍:科学上网,科学上网,科学上网。查看完整安装教程 →
swift-refactor by pproenca/dot-skills
npx skills add https://github.com/pproenca/dot-skills --skill swift-refactor将 Swift/SwiftUI 代码迁移到模块化 MVVM-C 架构的全面重构指南,包含本地 SPM 包边界和 App 目标组合根目录的布线。
┌───────────────────────────────────────────────────────────────┐
│ App 目标:DependencyContainer、Coordinators、Route Shells │
├───────────────────────────────────────────────────────────────┤
│ 功能模块:View + ViewModel(依赖 Domain + DesignSystem)│
├───────────────────────────────────────────────────────────────┤
│ Data 包:repositories、remote/local stores、sync、retry │
├───────────────────────────────────────────────────────────────┤
│ Domain 包:models、repository/coordinator/error protocols │
└───────────────────────────────────────────────────────────────┘
依赖规则:功能模块永不导入 Data,也永不导入同级功能模块。
本技能中的所有指南均假设采用诊所模块化 MVVM-C 架构:
Domain + DesignSystem(永不导入 Data,永不导入同级功能模块)广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
DependencyContainer、具体协调器和 Route Shell 布线Domain 保持纯 Swift,定义模型以及 repository、*Coordinating、ErrorRouting 和 AppError 契约Data 拥有 SwiftData/network/sync/retry/background I/O 并实现 Domain 协议在以下情况下参考本指南:
DependencyContainer 设置依赖注入.task(id:) 和可取消加载替换手动 Task 管理@Observable ViewModels/协调器,永不使用 ObservableObject / @PublishedNavigationStack 由 App 目标的路由外壳和协调器拥有@Equatable 宏,永不使用 AnyView| 优先级 | 类别 | 影响 | 前缀 | 规则数量 |
|---|---|---|---|---|
| 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 |
diff-equatable-views - 为每个 SwiftUI 视图添加 @Equatable 宏diff-closure-skip - 对闭包属性使用 @EquatableIgnoreddiff-identity-stability - 在 ForEach 中使用稳定的 O(1) 标识符diff-printchanges-debug - 使用 _printChanges() 诊断重新渲染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 修饰符替换 navigationBarItemsstate-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 的 @Stateview-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 - 将视图 body 减少到最多 10 个节点nav-centralize-destinations - 将导航重构为协调器模式nav-value-based-links - 用协调器路由替换 NavigationLinknav-path-state-management - 使用 NavigationPath 进行编程式导航nav-split-view-adoption - 对多列布局使用 NavigationSplitViewnav-sheet-item-pattern - 用 item 绑定替换布尔值 sheet 触发器layer-dependency-rule - 提取零框架导入的领域层layer-usecase-protocol - 移除 use-case/interactor 层;将编排保留在 ViewModel + repository 协议中layer-repository-protocol - Domain 中的 Repository 协议,Data 中的实现layer-no-view-repository - 移除视图中对 repository 的直接访问layer-viewmodel-boundary - 重构 ViewModels 以仅暴露可供显示的状态arch-viewmodel-elimination - 将内联状态重构为 @Observable ViewModelarch-protocol-dependencies - 通过 ViewModel 层提取协议依赖arch-environment-key-injection - 使用 Environment 键进行服务注入arch-feature-module-extraction - 将功能提取到独立模块中arch-model-view-separation - 将业务逻辑提取到 Domain 模型和 repository 支持的 ViewModels 中di-container-composition - 在应用根目录组合依赖容器di-mock-testing - 为每个协议依赖添加模拟实现type-tagged-identifiers - 用标记类型替换字符串 IDtype-result-over-optionals - 使用 Result 类型而非带错误标志的可选值type-phantom-types - 使用幻影类型实现编译时状态机type-force-unwrap-elimination - 用安全替代方案消除强制解包list-constant-viewcount - 确保 ForEach 为每个元素生成恒定的视图数量list-filter-in-model - 将筛选/排序逻辑从 ForEach 移到 ViewModel 中list-lazy-stacks - 对于无界内容,用 Lazy 变体替换 VStack/HStacklist-id-keypath - 提供显式的 id keyPath — 永不依赖隐式标识data-task-modifier - 用 .task 修饰符替换 onAppear 中的异步工作data-error-loadable - 将加载状态建模为枚举而非布尔标志data-cancellation - 使用 .task 自动取消 — 永不手动管理 Tasksswift-let-vs-var - 对常量使用 let,对变量使用 varswift-structs-vs-classes - 优先使用结构体而非类swift-camel-case-naming - 使用驼峰命名法swift-string-interpolation - 对动态文本使用字符串插值swift-functions-clear-names - 为函数和参数命名以保持清晰swift-for-in-loops - 对集合使用 for-in 循环swift-optionals - 通过解包安全处理可选值swift-closures - 对内联函数使用闭包阅读单独的参考文件以获取详细解释和代码示例:
| 文件 | 描述 |
|---|---|
| references/_sections.md | 类别定义和排序 |
| assets/templates/_template.md | 新规则模板 |
每周安装量
50
仓库
GitHub 星标数
88
首次出现
2026年2月8日
安全审计
安装于
codex46
gemini-cli45
kimi-cli44
claude-code44
github-copilot44
opencode44
Comprehensive refactoring guide for migrating Swift/SwiftUI code to modular MVVM-C with local SPM package boundaries and App-target composition root wiring.
┌───────────────────────────────────────────────────────────────┐
│ 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 Data and never import sibling features.
All guidance in this skill assumes the clinic modular MVVM-C architecture:
Domain + DesignSystem only (never Data, never sibling features)DependencyContainer, concrete coordinators, and Route Shell wiringDomain stays pure Swift and defines models plus repository, *Coordinating, ErrorRouting, and AppError contractsData owns SwiftData/network/sync/retry/background I/O and implements Domain protocolsReference these guidelines when:
DependencyContainer.task(id:) and cancellable loading@Observable ViewModels/coordinators, ObservableObject / @Published neverNavigationStack is owned by App-target route shells and coordinators@Equatable macro on every view, AnyView never| Priority | Category | Impact | Prefix | Rules |
|---|---|---|---|---|
| 1 | View Identity & Diffing | CRITICAL | diff- | 4 |
| 2 | API Modernization | CRITICAL | api- | 7 |
| 3 | State Architecture | CRITICAL | state- | 6 |
| 4 | View Composition | HIGH | view- |
diff-equatable-views - Add @Equatable macro to every SwiftUI viewdiff-closure-skip - Use @EquatableIgnored for closure propertiesdiff-identity-stability - Use stable O(1) identifiers in ForEachdiff-printchanges-debug - Use _printChanges() to diagnose re-rendersapi-observable-macro - Migrate ObservableObject to @Observable macroapi-navigationstack-migration - Replace NavigationView with NavigationStackapi-onchange-signature - Migrate to new onChange signatureapi-environment-object-removal - Replace @EnvironmentObject with @Environmentapi-alert-confirmation-dialog - Migrate Alert to confirmationDialog APIstate-scope-minimization - Minimize state scope to nearest consumerstate-derived-over-stored - Use computed properties over redundant @Statestate-binding-extraction - Extract @Binding to isolate child re-rendersstate-remove-observation - Migrate @ObservedObject to @Observable trackingstate-onappear-to-task - Replace onAppear closures with .task modifierview-extract-subviews - Extract subviews for diffing checkpointsview-eliminate-anyview - Replace AnyView with @ViewBuilder or genericsview-computed-to-struct - Convert computed view properties to struct viewsview-modifier-extraction - Extract repeated modifiers into custom ViewModifiersview-conditional-content - Use Group or conditional modifiers over conditional viewsnav-centralize-destinations - Refactor navigation to coordinator patternnav-value-based-links - Replace NavigationLink with coordinator routesnav-path-state-management - Use NavigationPath for programmatic navigationnav-split-view-adoption - Use NavigationSplitView for multi-column layoutsnav-sheet-item-pattern - Replace boolean sheet triggers with item bindinglayer-dependency-rule - Extract domain layer with zero framework importslayer-usecase-protocol - Remove use-case/interactor layer; keep orchestration in ViewModel + repository protocolslayer-repository-protocol - Repository protocols in Domain, implementations in Datalayer-no-view-repository - Remove direct repository access from viewslayer-viewmodel-boundary - Refactor ViewModels to expose display-ready state onlyarch-viewmodel-elimination - Restructure inline state into @Observable ViewModelarch-protocol-dependencies - Extract protocol dependencies through ViewModel layerarch-environment-key-injection - Use Environment keys for service injectionarch-feature-module-extraction - Extract features into independent modulesarch-model-view-separation - Extract business logic into Domain models and repository-backed ViewModelsdi-container-composition - Compose dependency container at app rootdi-mock-testing - Add mock implementation for every protocol dependencytype-tagged-identifiers - Replace String IDs with tagged typestype-result-over-optionals - Use Result type over optional with error flagtype-phantom-types - Use phantom types for compile-time state machinestype-force-unwrap-elimination - Eliminate force unwraps with safe alternativeslist-constant-viewcount - Ensure ForEach produces constant view count per elementlist-filter-in-model - Move filter/sort logic from ForEach into ViewModellist-lazy-stacks - Replace VStack/HStack with Lazy variants for unbounded contentlist-id-keypath - Provide explicit id keyPath — never rely on implicit identitydata-task-modifier - Replace onAppear async work with .task modifierdata-error-loadable - Model loading states as enum instead of boolean flagsdata-cancellation - Use .task automatic cancellation — never manage Tasks manuallyswift-let-vs-var - Use let for constants, var for variablesswift-structs-vs-classes - Prefer structs over classesswift-camel-case-naming - Use camelCase naming conventionswift-string-interpolation - Use string interpolation for dynamic textswift-functions-clear-names - Name functions and parameters for clarityRead individual reference files for detailed explanations and code examples:
| File | Description |
|---|---|
| references/_sections.md | Category definitions and ordering |
| assets/templates/_template.md | Template for new rules |
Weekly Installs
50
Repository
GitHub Stars
88
First Seen
Feb 8, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
codex46
gemini-cli45
kimi-cli44
claude-code44
github-copilot44
opencode44
Kotlin Ktor 服务器模式指南:构建健壮 HTTP API 的架构与最佳实践
1,400 周安装
AI驱动知识库搜索工具 - Nowledge Mem搜索记忆技能,提升开发效率
440 周安装
Tailwind设计系统:构建生产就绪的组件库与响应式UI模式
439 周安装
SDD实施带验证任务:自动化质量验证与迭代修复的AI开发工具
441 周安装
workflow-init:Vercel Workflow DevKit 自动化初始化工具,支持 Next.js/Nuxt/SvelteKit 等主流框架
445 周安装
feishu-cli-msg:命令行发送飞书消息与互动,支持文本/文件/图片/卡片
446 周安装
distill-memory 知识提炼工具:智能会话记忆管理,提升开发效率与决策连续性
443 周安装
| 7 |
| 5 | Navigation & Coordination | HIGH | nav- | 5 |
| 6 | Layer Architecture | HIGH | layer- | 5 |
| 7 | Architecture Patterns | HIGH | arch- | 5 |
| 8 | Dependency Injection | MEDIUM-HIGH | di- | 2 |
| 9 | Type Safety & Protocols | MEDIUM-HIGH | type- | 4 |
| 10 | List & Collection Performance | MEDIUM | list- | 4 |
| 11 | Async & Data Flow | MEDIUM | data- | 3 |
| 12 | Swift Language Fundamentals | MEDIUM | swift- | 8 |
api-list-foreach-identifiableapi-toolbar-migration - Replace navigationBarItems with toolbar modifierstate-stateobject-placementview-preference-keysview-body-complexity - Reduce view body to maximum 10 nodesswift-for-in-loopsswift-optionals - Handle optionals safely with unwrappingswift-closures - Use closures for inline functions