swift-6-agent-skill
4
总安装量
3
周安装量
#52608
全站排名
安装命令
npx skills add https://github.com/pchelnikov/swift-6-agent-skill --skill swift-6-agent-skill
Agent 安装分布
opencode
3
claude-code
3
github-copilot
3
codex
3
kimi-cli
3
gemini-cli
3
Skill 文档
Swift Modern Patterns (6.0â6.2)
Overview
Use this skill to ensure Swift code uses current language features and avoids deprecated or outdated patterns. It covers Swift 6.0, 6.1, and 6.2 with SE-proposal-level traceability. This skill focuses on language-level features and best practices without enforcing specific architectures.
Workflow Decision Tree
1) Generate new Swift code
- Determine the target Swift version and language mode (5 vs 6)
- Use modern concurrency patterns by default (see Concurrency Guidelines)
- Apply typed throws where the error set is fixed and internal (see
references/SWIFT_6_0.md) - Use
@Observable+Observationsfor reactive state outside SwiftUI (SE-0475, seereferences/SWIFT_6_2.md) - Use trailing commas in multi-line parameter lists (SE-0439)
- Use raw identifiers for test names (SE-0451, see
references/SWIFT_6_2.md) - Name all tasks for debuggability (SE-0469)
- Prefer
InlineArrayfor fixed-size collections (SE-0453, seereferences/SWIFT_6_2.md)
2) Review existing Swift code
- Check for deprecated or outdated patterns against the Quick Reference table below
- Audit concurrency safety: global variables, actor isolation, Sendable conformance (see
references/SWIFT_6_0.md) - Verify
@MainActorannotations are explicit where needed post-SE-0401 - Check import visibility: transitive imports should be explicit (SE-0444, see
references/SWIFT_6_1.md) - Look for unnecessary
@unchecked Sendableâ compiler region analysis (SE-0414) may make them redundant - Verify test code uses Swift Testing patterns, not legacy XCTest (see Testing)
- Run through the Review Checklist systematically
3) Refactor or migrate Swift 5.x â 6.x
- Read
references/MIGRATION.mdfor comprehensive old â new mappings with before/after code - Start with concurrency: enable strict checking, resolve global variable warnings (SE-0412)
- Add explicit
@MainActorto views using@StateObject/@ObservedObject(SE-0401) - Consider enabling
-default-isolation MainActorfor UI-focused modules (SE-0466, Swift 6.2+) - Replace implicit imports with explicit per-file imports (SE-0444)
- Upgrade test suites:
#expect(throws:)return values (ST-0006), exit tests (ST-0008) - For version-specific details, see
references/SWIFT_6_0.md,references/SWIFT_6_1.md,references/SWIFT_6_2.md
4) Debug concurrency warnings or errors
- “Sending value of non-Sendable type…” â Check if compiler region analysis (SE-0414) resolves it; if not, see
references/SWIFT_6_0.mdforsendingkeyword (SE-0430) - “Main actor-isolated … cannot be used from nonisolated context” â Verify
@MainActorannotations; considernonisolatedat type level (SE-0449, seereferences/SWIFT_6_1.md) - “Global variable … is not concurrency-safe” â Make it
let, isolate to@MainActor, or usenonisolated(unsafe)as last resort (SE-0412, seereferences/SWIFT_6_0.md) - Nonisolated async running on wrong actor â In Swift 6.2+, nonisolated async inherits caller’s actor (SE-0461); use
@concurrentto opt out (seereferences/SWIFT_6_2.md) - Deinit cannot access actor-isolated state â Use
isolated deinit(SE-0371, Swift 6.2+, seereferences/SWIFT_6_2.md)
5) Answer questions about Swift features
- Identify the Swift version the question relates to
- Route to the appropriate reference file for syntax and examples
- Always cite SE proposal numbers when explaining features
Core Guidelines
Concurrency
- Default to MainActor isolation when appropriate. For app/UI modules in Swift 6.2+, prefer
-default-isolation MainActorand only opt out withnonisolatedor@concurrentwhere background work is genuinely needed (SE-0466). - Trust the compiler’s isolation region analysis. Do not add unnecessary
@Sendableconformances or@unchecked Sendablewhen the compiler can prove safety through region isolation (SE-0414). - Use
Mutexfor shared mutable state â preferMutexfrom the Synchronization library overNSLockoros_unfair_lock. UseAtomicfor simple lock-free flags and counters (SE-0433, SE-0410). - Use
nonisolatedon types to opt out of inherited actor isolation at the type level rather than annotating every member (SE-0449, Swift 6.1+). - Prefer
Task.immediatewhen the task must begin executing synchronously from the caller’s context before any suspension point (SE-0472, Swift 6.2+). - Name tasks for debuggability. Always pass a
name:parameter toTask.init(),Task.detached(), andaddTask()in task groups (SE-0469, Swift 6.2+). - Understand nonisolated async changes. Nonisolated async functions now run on the caller’s actor by default. Use
@concurrentto opt into the old hop-off behavior (SE-0461, Swift 6.2+). - Use
isolated deinitfor actor-isolated classes that need safe cleanup of non-Sendable state (SE-0371, Swift 6.2+). - Use global-actor isolated conformances when protocol conformance requires access to actor-isolated state, e.g.,
@MainActor Equatable(SE-0470, Swift 6.2+).
Error Handling
- Prefer typed throws for constrained domains where the error set is fixed and known (internal modules, embedded Swift). Use untyped
throwsfor public library APIs to preserve flexibility (SE-0413). - Leverage typed throws in generic contexts â
throws(E)enablesthrows(Never)inference for non-throwing closures, eliminating unnecessary do/catch.
Types and Data
- Use
InlineArrayfor fixed-size collections where the count is known at compile time. Prefer[N of T]sugar syntax (SE-0483). Note: does not conform toSequence/Collectionâ iterate via.indices(SE-0453, Swift 6.2+). - Use
weak letfor immutable weak references, especially inSendabletypes whereweak varwould prevent conformance (SE-0481, Swift 6.2+). - Prefer noncopyable types (
~Copyable) for unique-ownership semantics.OptionalandResultnow support noncopyable wrapped types (SE-0427, SE-0437, Swift 6.0+).
Observation
- Use
Observationsfor programmatic observation of@Observablechanges outside SwiftUI â replaces manual KVO or Combine-based observation (SE-0475, Swift 6.2+).
Debugging
- Use
@DebugDescriptionon types withCustomDebugStringConvertibleto enable custom formatting in LLDB’spcommand and Xcode’s variables view (SE-0440, Swift 6.0+).
Enums and API Design
- Leave public package enums extensible â do not add
@frozenunless the case list is genuinely complete and will never grow. This allows adding cases in minor versions without breaking consumers (SE-0487, Swift 6.2.3+). - Add
@unknown defaultto switches over public enums from external packages to future-proof against new cases. - Add
@retroactivewhen conforming external types to external protocols to acknowledge the retroactive conformance and silence the compiler warning (SE-0364, Swift 6.0+).
Code Style
- Use trailing commas in multi-line parameter lists, arrays, and generics. Improves diff quality and commenting convenience (SE-0439, Swift 6.1+).
- Use raw identifiers for human-readable test names and enum cases starting with numbers (SE-0451, Swift 6.2+).
- Use default values in string interpolation â
\(optional, default: "fallback")supports cross-type defaults (SE-0477, Swift 6.2+).
Imports and Modules
- Use access-level import modifiers â
internal importorprivate importto prevent accidental API leakage (SE-0409, Swift 6.0+). - Enable
MemberImportVisibilityflag to require explicit imports per file (SE-0444, Swift 6.1+).
Testing
- Prefer Swift Testing over XCTest for new test targets. Use
@Test,#expect,#require. - Use range-based confirmations â
confirmation(expectedCount: 5...10)(ST-0005, Swift 6.1+). - Use returned errors from
#expect(throws:)instead of the deprecated dual-trailing-closure form (ST-0006, Swift 6.1+). - Use test scoping traits for concurrency-safe shared test configuration via
TestScopingprotocol (ST-0007, Swift 6.1+). - Use exit tests â
#expect(processExitsWith: .failure)for testingprecondition/fatalErrorpaths (ST-0008, Swift 6.2+). - Use test attachments â
Attachment.record(value, named:)for debugging failing tests (ST-0009, Swift 6.2+).
Quick Reference: Old â New
| Deprecated / Outdated | Modern Replacement | Since | SE |
|---|---|---|---|
Bare global var |
let, @MainActor var, or nonisolated(unsafe) |
6.0 | SE-0412 |
@StateObject infers @MainActor |
Explicit @MainActor on view required |
6.0 | SE-0401 |
| Catch-all for exhaustive error types | throws(SpecificError) eliminates catch-all |
6.0 | SE-0413 |
withTaskGroup(of: T.self) |
withTaskGroup { } (type inferred) |
6.1 | SE-0442 |
Per-member nonisolated |
nonisolated struct/class at type level |
6.1 | SE-0449 |
| Transitive imports leak across files | Enable MemberImportVisibility flag |
6.1 | SE-0444 |
#expect { } throws: { } (dual closure) |
let error = #expect(throws: T.self) { } |
6.1 | ST-0006 |
Manual @MainActor on every type |
-default-isolation MainActor per module |
6.2 | SE-0466 |
camelCase test names + @Test("...") |
Raw identifiers: @Test func `readable name`() |
6.2 | SE-0451 |
| Nonisolated async hops off actor | Now stays on caller’s actor; @concurrent to opt out |
6.2 | SE-0461 |
Task { } for immediate work |
Task.immediate { } runs synchronously until first await |
6.2 | SE-0472 |
weak var in Sendable types |
weak let enables Sendable conformance |
6.2 | SE-0481 |
Combine/KVO for @Observable changes |
Observations { } AsyncSequence |
6.2 | SE-0475 |
| Tuples for fixed-size data | InlineArray<N, T> with subscript access |
6.2 | SE-0453 |
\(optional ?? "fallback") (same type only) |
\(optional, default: "fallback") (cross-type) |
6.2 | SE-0477 |
Regular deinit in actor-isolated class |
isolated deinit for safe cleanup |
6.2 | SE-0371 |
InlineArray<N, T> (verbose) |
[N of T] sugar syntax |
6.2 | SE-0483 |
NSLock / os_unfair_lock |
Mutex from Synchronization library |
6.0 | SE-0433 |
| Manual atomic operations / locks for flags | Atomic<Value> from Synchronization library |
6.0 | SE-0410 |
No LLDB summary from debugDescription |
@DebugDescription macro enables p command formatting |
6.0 | SE-0440 |
| Silent retroactive conformance | @retroactive annotation required (compiler warning) |
6.0 | SE-0364 |
String(bytes:encoding:) |
String(validating:as: UTF8.self) returns Optional |
6.0 | SE-0405 |
| Adding enum case = SemVer-major break | Extensible by default; @frozen to opt out |
6.2.3 | SE-0487 |
Review Checklist
Concurrency Safety
- No bare mutable global variables (must be
let, actor-isolated, ornonisolated(unsafe)) - Views using
@StateObject/@ObservedObjecthave explicit@MainActor - No unnecessary
@unchecked Sendableâ check if region analysis handles it - Shared mutable state uses
MutexorAtomic, notNSLock/os_unfair_lock - Tasks are named with
name:parameter -
nonisolated asyncbehavior is intentional (caller-inheriting in 6.2+ vs hop-off in <6.2) -
isolated deinitused where actor-isolated class accesses non-Sendable state in cleanup
Error Handling
- Typed throws used for internal/fixed error sets; untyped throws for public APIs
- No unnecessary catch-all blocks when typed throws covers all cases
Modern Patterns
-
InlineArrayuses[N of T]sugar syntax where available -
weak letused instead ofweak varwhere immutability suffices (enablesSendable) -
Observationsused instead of Combine/KVO for@Observableoutside SwiftUI - String interpolation uses
default:parameter for optional cross-type fallbacks - Trailing commas in multi-line lists
-
@DebugDescriptionused on types withCustomDebugStringConvertible -
String(validating:as:)used instead ofString(bytes:encoding:)for safe encoding
Imports
- No transitive import dependencies (
MemberImportVisibilityenabled) - Access-level imports used to prevent API leakage (
internal import,private import)
API Design
- Public package enums: extensible by default,
@frozenonly when case list is truly fixed - Consumer
switchover external enums includes@unknown default - Retroactive conformances annotated with
@retroactive
Testing
- Swift Testing preferred over XCTest for new tests
-
#expect(throws:)returns error for separate validation (not dual-closure form) - Exit tests used for
precondition/fatalErrorpaths - Test scoping traits used for shared configuration (not mutable shared state)
- Raw identifiers used for readable test names
Version Coverage
| Version | Release | Key Features |
|---|---|---|
| 6.0 | Sep 2024 | Complete concurrency by default, typed throws, Mutex/Atomics, noncopyable upgrades, RangeSet, Int128 |
| 6.1 | Spring 2025 | Trailing commas, metatype key paths, diagnostic groups, nonisolated types, import visibility |
| 6.2 | WWDC 2025 | Default MainActor isolation, raw identifiers, InlineArray + [N of T] sugar, immediate tasks, weak let, Observations |
| 6.2.3 | Late 2025 | Extensible enums for non-resilient modules (SE-0487) |
References
references/SWIFT_6_0.mdâ Concurrency defaults, Mutex/Atomics, typed throws, @DebugDescription, noncopyable upgrades, AsyncSequence generics, RangeSet, Int128, BitwiseCopyablereferences/SWIFT_6_1.mdâ Trailing commas, metatype key paths, TaskGroup inference, nonisolated types, import visibility, diagnostic groups, Swift Testing improvementsreferences/SWIFT_6_2.mdâ Default MainActor isolation, raw identifiers, InlineArray +[N of T]sugar, immediate tasks, weak let, Observations, Span/MutableSpan, method key paths, exit testsreferences/SWIFT_6_2_3.mdâ Extensible enums for non-resilient modules (SE-0487)references/MIGRATION.mdâ Comprehensive old â new pattern mappings with before/after code for all versions
Philosophy
This skill focuses on language-level facts and best practices, not opinions:
- No architecture enforcement. We don’t prescribe MVVM, TCA, VIPER, or any pattern. We suggest modern language features; how you structure your app is your decision.
- No formatting or linting rules. Property ordering, brace style, and line length are out of scope.
- SE-proposal grounded. Every recommendation traces to a Swift Evolution proposal. If it’s not in an SE, it’s not in this skill.
- Version-aware. Every feature is tagged with the Swift version that introduced it. The agent should not suggest Swift 6.2 features to a project targeting Swift 6.0.
- Practical over comprehensive. The agent’s context window is finite. These files contain what matters for day-to-day code generation and review, not exhaustive API documentation.