swift-concurrency

安装量: 5.3K
排名: #574

安装

npx skills add https://github.com/avdlee/swift-concurrency-agent-skill --skill swift-concurrency
Swift Concurrency
Fast Path
Before proposing a fix:
Analyze
Package.swift
or
.pbxproj
to determine Swift language mode, strict concurrency level, default isolation, and upcoming features. Do this always, not only for migration work.
Capture the exact diagnostic and offending symbol.
Determine the isolation boundary:
@MainActor
, custom actor, actor instance isolation, or
nonisolated
.
Confirm whether the code is UI-bound or intended to run off the main actor.
Project settings that change concurrency behavior:
Setting
SwiftPM (
Package.swift
)
Xcode (
.pbxproj
)
Language mode
swiftLanguageVersions
or
-swift-version
(
// swift-tools-version:
is not a reliable proxy)
Swift Language Version
Strict concurrency
.enableExperimentalFeature("StrictConcurrency=targeted")
SWIFT_STRICT_CONCURRENCY
Default isolation
.defaultIsolation(MainActor.self)
SWIFT_DEFAULT_ACTOR_ISOLATION
Upcoming features
.enableUpcomingFeature("NonisolatedNonsendingByDefault")
SWIFT_UPCOMING_FEATURE_*
If any of these are unknown, ask the developer to confirm them before giving migration-sensitive guidance. Do not guess.
Guardrails:
Do not recommend
@MainActor
as a blanket fix. Justify why the code is truly UI-bound.
Prefer structured concurrency over unstructured tasks. Use
Task.detached
only with a clear reason.
If recommending
@preconcurrency
,
@unchecked Sendable
, or
nonisolated(unsafe)
, require a documented safety invariant and a follow-up removal plan.
Optimize for the smallest safe change. Do not refactor unrelated architecture during migration.
Course references are for deeper learning only. Use them sparingly and only when they clearly help answer the developer's question.
Quick Fix Mode
Use Quick Fix Mode when all of these are true:
The issue is localized to one file or one type.
The isolation boundary is clear.
The fix can be explained in 1-2 behavior-preserving steps.
Skip Quick Fix Mode when any of these are true:
Build settings or default isolation are unknown.
The issue crosses module boundaries or changes public API behavior.
The likely fix depends on unsafe escape hatches.
Common Diagnostics
Diagnostic
First check
Smallest safe fix
Escalate to
Main actor-isolated ... cannot be used from a nonisolated context
Is this truly UI-bound?
Isolate the caller to
@MainActor
or use
await MainActor.run
only when main-actor ownership is correct.
references/actors.md
,
references/threading.md
Actor-isolated type does not conform to protocol
Must the requirement run on the actor?
Prefer isolated conformance (e.g.,
extension Foo: @MainActor SomeProtocol
); use
nonisolated
only for truly nonisolated requirements.
references/actors.md
Sending value of non-Sendable type ... risks causing data races
What isolation boundary is being crossed?
Keep access inside one actor, or convert the transferred value to an immutable/value type.
references/sendable.md
,
references/threading.md
SwiftLint async_without_await
Is
async
actually required by protocol, override, or
@concurrent
?
Remove
async
, or use a narrow suppression with rationale. Never add fake awaits.
references/linting.md
wait(...) is unavailable from asynchronous contexts
Is this legacy XCTest async waiting?
Replace with
await fulfillment(of:)
or Swift Testing equivalents.
references/testing.md
Core Data concurrency warnings
Are
NSManagedObject
instances crossing contexts or actors?
Pass
NSManagedObjectID
or map to a Sendable value type.
references/core-data.md
Thread.current
unavailable from asynchronous contexts
Are you debugging by thread instead of isolation?
Reason in terms of isolation and use Instruments/debugger instead.
references/threading.md
SwiftLint concurrency-related warnings
Which specific lint rule triggered?
Use
references/linting.md
for rule intent and preferred fixes; avoid dummy awaits.
references/linting.md
When Quick Fixes Fail
Gather project settings if not already confirmed.
Re-evaluate which isolation boundaries the type crosses.
Route to the matching reference file for a deeper fix.
If the fix may change behavior, document the invariant and add verification steps.
Smallest Safe Fixes
Prefer changes that preserve behavior while satisfying data-race safety:
UI-bound state
isolate the type or member to
@MainActor
.
Shared mutable state
move it behind an
actor
, or use
@MainActor
only if the state is UI-owned.
Background work
when work must hop off caller isolation, use an
async
API marked
@concurrent
; when work can safely inherit caller isolation, use
nonisolated
without
@concurrent
.
Sendability issues
prefer immutable values and explicit boundaries over
@unchecked Sendable
.
Concurrency Tool Selection
Need
Tool
Key Guidance
Single async operation
async/await
Default choice for sequential async work
Fixed parallel operations
async let
Known count at compile time; auto-cancelled on throw
Dynamic parallel operations
withTaskGroup
Unknown count; structured — cancels children on scope exit
Sync → async bridge
Task { }
Inherits actor context; use
Task.detached
only with documented reason
Shared mutable state
actor
Prefer over locks/queues; keep isolated sections small
UI-bound state
@MainActor
Only for truly UI-related code; justify isolation
Common Scenarios
Network request with UI update
Task
{
@concurrent
in
let
data
=
try
await
fetchData
(
)
await
MainActor
.
run
{
self
.
updateUI
(
with
:
data
)
}
}
Processing array items in parallel
await
withTaskGroup
(
of
:
ProcessedItem
.
self
)
{
group
in
for
item
in
items
{
group
.
addTask
{
await
process
(
item
)
}
}
for
await
result
in
group
{
results
.
append
(
result
)
}
}
Swift 6 Migration Quick Guide
Key changes in Swift 6:
Strict concurrency checking
enabled by default
Complete data-race safety
at compile time
Sendable requirements
enforced on boundaries
Isolation checking
for all async boundaries
Migration Validation Loop
Apply this cycle for each migration change:
Build
— Run
swift build
or Xcode build to surface new diagnostics
Fix
— Address one category of error at a time (e.g., all Sendable issues first)
Rebuild
— Confirm the fix compiles cleanly before moving on
Test
— Run the test suite to catch regressions (
swift test
or Cmd+U)
Only proceed
to the next file/module when all diagnostics are resolved
If a fix introduces new warnings, resolve them before continuing. Never batch multiple unrelated fixes — keep commits small and reviewable.
For detailed migration steps, see
references/migration.md
.
Reference Router
Open the smallest reference that matches the question:
Foundations
references/async-await-basics.md
— async/await syntax, execution order, async let, URLSession patterns
references/tasks.md
— Task lifecycle, cancellation, priorities, task groups, structured vs unstructured
references/actors.md
— Actor isolation, @MainActor, global actors, reentrancy, custom executors, Mutex
references/sendable.md
— Sendable conformance, value/reference types, @unchecked, region isolation
references/threading.md
— Execution model, suspension points, Swift 6.2 isolation behavior
Streams
references/async-sequences.md
— AsyncSequence, AsyncStream, when to use vs regular async methods
references/async-algorithms.md
— Debounce, throttle, merge, combineLatest, channels, timers
Applied topics
references/testing.md
— Swift Testing first, XCTest fallback, leak checks
references/performance.md
— Profiling with Instruments, reducing suspension points, execution strategies
references/memory-management.md
— Retain cycles in tasks, memory safety patterns
references/core-data.md
— NSManagedObject sendability, custom executors, isolation conflicts
Migration and tooling
references/migration.md
— Swift 6 migration strategy, closure-to-async conversion, @preconcurrency, FRP migration
references/linting.md
— Concurrency-focused lint rules and SwiftLint
async_without_await
Glossary
references/glossary.md
— Quick definitions of core concurrency terms
Verification Checklist
When changing concurrency code:
Re-check build settings before interpreting diagnostics.
Build and clear one category of errors before moving on. Do not batch unrelated fixes into the same change.
Run tests, especially actor-, lifetime-, and cancellation-sensitive tests.
Use Instruments for performance claims instead of guessing.
Verify deallocation and cancellation behavior for long-lived tasks.
Check
Task.isCancelled
in long-running operations.
Never use semaphores or ad hoc locking in async contexts when actor isolation or
Mutex
would express ownership more safely.
Note
This skill is based on the comprehensive Swift Concurrency Course by Antoine van der Lee.
返回排行榜