Install any skill in seconds. Free to start, no credit card required.
Get Started Free →avdlee/swift-concurrency
Diagnose Swift Concurrency issues, refactor callback-based code to async/await, and guide Swift 6 migration when working with tasks, actors, @MainActor, Sendable, data races, thread safety, or concurrency-related compiler and linter warnings.
Passed 19 of 22 test cases with the skill, and 16 of 22 without it.
3 fixed16 passed either way3 still failing0 broke
Tokens, turns and time describe resource use, not a dollar price.
One of 3 test cases the skill fixed. Same model, same prompt, with and without the skill.
We have a method on a `@MainActor` view model that needs to start a background download task. The first line of the task prints a log statement, followed by an `await downloadData()`, followed by updating a main-actor property. Should we start the task with `Task { @concurrent in ... }` or rely on inherited `@MainActor` context?
| Checked | Without skill | With skill |
|---|---|---|
| Recommend using `Task { @concurrent in ... }` because the synchronous prefix does not require main-actor state. | Missed | Passed |
The instructions your model reads when the skill loads.
Before proposing a fix:
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.@MainActor, custom actor, actor instance isolation, or nonisolated.await): start on @MainActor only when that prefix truly needs main-actor access; otherwise use Task { @concurrent in ... } and hop back with MainActor.run only after the suspension. A trivial non-main line (for example, print) followed by main-actor work in the same prefix is not a reason to use @concurrent. For delayed retries, timers, and backoff tasks, separate the waiting from the UI mutation. The sleep often belongs off the main actor even when the final state update belongs on it.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_* |
| Approachable Concurrency | N/A (use individual upcoming features) | SWIFT_APPROACHABLE_CONCURRENCY |
Xcode 26 note: New projects created in Xcode 26 will often start with
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActorandSWIFT_APPROACHABLE_CONCURRENCY = YESenabled by default. Treat these as likely defaults for newly created projects, not as confirmed settings.
If any of these are unknown, ask the developer to confirm them before giving migration-sensitive guidance. Do not guess, even for new Xcode 26 projects.
Guardrails:
@MainActor as a blanket fix. Justify why the code is truly UI-bound.Task.detached only with a clear reason.@preconcurrency, @unchecked Sendable, or nonisolated(unsafe), require a documented safety invariant and a follow-up removal plan.Use Quick Fix Mode when all of these are true:
test cases passed, vs 16 / 22 without
Published skills whose descriptions closely match this one, with their headline benchmark lift.
More skills from the same source and nearby in the registry, with their headline benchmark lift.