技能创建器
skill-creator
创建、改进和评估自定义技能,把专业流程转化为可重复使用的 AI 能力。
swift-refactor【数据与研究】Swift and SwiftUI refactoring patterns aligned with the iOS 26 / Swift 6.2 clinic modular MVVM-C architecture (Airbnb + OLX SPM layout). Enforces @Observable ViewModels/coordinators, App-target `DependencyContainer` + route shells, Domain repository/coordinator/error-routing protocols, and Data-owned I/O with stale-while-revalidate plus optimistic qu…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
DependencyContainer + route shells, Domain repository/coordinator/error-routing protocols, and Data-owned I/O with stale-while-revalidate plus optimistic queued sync boundaries. Use when refactoring existing SwiftUI code into the clinic architecture.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- | 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 |
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 APIapi-list-foreach-identifiable - Replace id: .self with Identifiable conformanceapi-toolbar-migration - Replace navigationBarItems with toolbar modifierstate-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 modifierstate-stateobject-placement - Migrate @StateObject to @State with @Observableview-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 viewsview-preference-keys - Replace callback closures with PreferenceKeyview-body-complexity - Reduce view body to maximum 10 nodesnav-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 clarityswift-for-in-loops - Use for-in loops for collectionsswift-optionals - Handle optionals safely with unwrappingswift-closures - Use closures for inline functionsRead 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 |