swift-concurrency-updates
Swift 6.2 concurrency updates including default MainActor inference, @concurrent for background work, isolated conformances, and approachable concurrency migration. Use when adopting Swift 6.2 concurrency features or fixing data-race errors.
What this skill does
# Swift 6.2 Concurrency Updates
Swift 6.2 introduces "Approachable Concurrency" -- a set of changes that make strict concurrency dramatically easier to adopt. The philosophy shifts from "opt in to safety" to "safe by default, opt in to concurrency." Code runs on `@MainActor` by default, async functions stay on the calling actor, and you explicitly request background execution with `@concurrent`.
This skill covers only the Swift 6.2 specific changes. For general concurrency patterns (actors, TaskGroup, AsyncSequence, Sendable, cancellation), see the `swift/concurrency-patterns` skill.
## When This Skill Activates
- User is adopting Swift 6.2 concurrency features
- User asks about default MainActor inference or the "infer main actor" build setting
- User encounters data-race errors that Swift 6.2 resolves
- User asks about `@concurrent`, isolated conformances, or approachable concurrency
- User wants to migrate from Swift 6.0/6.1 strict concurrency to 6.2
- User asks how async functions behave differently in Swift 6.2
- User needs to offload CPU-intensive work to a background thread in Swift 6.2
## What Changed in Swift 6.2 vs Before
### The Core Problem with Swift 6.0/6.1
In Swift 6.0 and 6.1, strict concurrency was correct but painful. Developers faced walls of data-race compiler errors that were difficult to resolve. Non-actor-annotated async functions would eagerly hop to the generic concurrent executor, causing unexpected data races when passing mutable state. Conforming `@MainActor` types to non-isolated protocols was often impossible without workarounds.
### Swift 6.2 Changes at a Glance
| Feature | Before (6.0/6.1) | After (6.2) |
|---------|------------------|-------------|
| Default isolation | Nothing inferred; manual `@MainActor` everywhere | Opt-in mode infers `@MainActor` on everything |
| Async function execution | Hops to generic concurrent executor | Stays on calling actor |
| `@MainActor` type conforming to protocol | Compiler error for non-isolated protocols | Isolated conformances: `@MainActor Protocol` |
| Background execution | `Task.detached` or manual nonisolated functions | `@concurrent` attribute |
| Global/static mutable state | Required `@MainActor` annotation or Sendable | Default MainActor mode handles it automatically |
---
## 1. Async Functions Stay on the Calling Actor
In Swift 6.0/6.1, a non-actor-annotated async function called from a `@MainActor` context would hop off the main actor to the generic concurrent executor. This caused data-race errors when the caller passed non-Sendable state.
In Swift 6.2, async functions without specific actor isolation stay on whatever actor they are called from. No hop, no data race.
### Before (Swift 6.0/6.1)
```swift
// ❌ Swift 6.0/6.1 -- ERROR: Sending 'self.processor' risks causing data races
@MainActor
final class StickerModel {
let processor = PhotoProcessor()
func extract(_ item: PhotosPickerItem) async throws -> Sticker? {
let data = try await item.loadTransferable(type: Data.self)
// processor hops off MainActor -- data race
return await processor.extractSticker(data: data, with: item.itemIdentifier)
}
}
class PhotoProcessor {
func extractSticker(data: Data, with id: String?) async -> Sticker? {
// This runs on the concurrent executor in 6.0/6.1
...
}
}
```
### After (Swift 6.2)
```swift
// ✅ Swift 6.2 -- No error. extractSticker stays on the caller's actor.
@MainActor
final class StickerModel {
let processor = PhotoProcessor()
func extract(_ item: PhotosPickerItem) async throws -> Sticker? {
let data = try await item.loadTransferable(type: Data.self)
// processor stays on MainActor -- no data race
return await processor.extractSticker(data: data, with: item.itemIdentifier)
}
}
class PhotoProcessor {
func extractSticker(data: Data, with id: String?) async -> Sticker? {
// In 6.2, this runs on MainActor because the caller is @MainActor
...
}
}
```
**Why this matters:** Many data-race errors in Swift 6.0/6.1 were caused by this implicit hop. In 6.2, the same code compiles cleanly with no changes needed.
---
## 2. Default MainActor Inference Mode
An opt-in build setting that makes all code implicitly `@MainActor` unless explicitly opted out with `nonisolated`. This eliminates the vast majority of data-race errors for single-threaded app code.
### Enabling It
**Xcode:** Build Settings > Swift Compiler - Concurrency > "Default Actor Isolation" > "MainActor"
**Swift Package Manager:**
```swift
.executableTarget(
name: "MyApp",
swiftSettings: [
.defaultIsolation(MainActor.self)
]
)
```
### What Changes
With this mode enabled, you no longer need `@MainActor` annotations on app-level types:
```swift
// ❌ Before (Swift 6.0/6.1) -- manual @MainActor annotations everywhere
@MainActor
final class StickerLibrary {
static let shared: StickerLibrary = .init()
}
@MainActor
final class StickerModel {
let processor: PhotoProcessor
var selection: [PhotosPickerItem]
}
@MainActor
struct ContentView: View {
@State private var model = StickerModel()
var body: some View { ... }
}
```
```swift
// ✅ After (Swift 6.2 with default MainActor inference) -- no annotations needed
final class StickerLibrary {
static let shared: StickerLibrary = .init() // Implicitly @MainActor
}
final class StickerModel {
let processor: PhotoProcessor // Implicitly @MainActor
var selection: [PhotosPickerItem]
}
struct ContentView: View {
@State private var model = StickerModel()
var body: some View { ... }
}
```
### When to Use Default MainActor Inference
| Target Type | Recommended? | Reason |
|-------------|-------------|--------|
| App target | Yes | Apps are UI-driven; most code belongs on MainActor |
| Script / executable | Yes | Scripts are sequential; MainActor default is natural |
| Library / framework | No | Libraries must not impose actor isolation on consumers |
| Package plugin | No | Same reasoning as libraries |
### Opting Out with nonisolated
When a type or function genuinely needs to run off the main actor, mark it `nonisolated`:
```swift
// With "infer main actor" enabled, use nonisolated to opt out:
nonisolated struct ImageProcessor {
func processImage(_ data: Data) -> UIImage {
// Runs on any thread, not MainActor
...
}
}
nonisolated func heavyComputation() -> Result {
// Runs on any thread
...
}
```
### Global and Static State Protection
With default MainActor inference enabled, global and static mutable state is automatically protected:
```swift
// ❌ Before -- required explicit annotation or Sendable conformance
@MainActor static let shared: StickerLibrary = .init()
// ✅ After -- default MainActor inference handles it
static let shared: StickerLibrary = .init() // Implicitly @MainActor
```
Without default MainActor inference, you can still protect individual declarations:
```swift
@MainActor static let shared: StickerLibrary = .init()
```
---
## 3. Isolated Conformances
Allows `@MainActor` types to conform to protocols that do not require actor isolation. Before Swift 6.2, this was a common source of frustrating compiler errors.
### The Problem (Swift 6.0/6.1)
```swift
protocol Exportable {
func export()
}
@MainActor
final class StickerModel {
let processor: PhotoProcessor
func doExport() {
processor.exportAsPNG()
}
}
// ❌ Swift 6.0/6.1 -- ERROR: Main actor-isolated conformance crosses isolation boundary
extension StickerModel: Exportable {
func export() {
processor.exportAsPNG() // Needs MainActor, but protocol is non-isolated
}
}
```
### The Solution (Swift 6.2)
```swift
// ✅ Swift 6.2 -- Isolated conformance
extension StickerModel: @MainActor Exportable {
func export() {
processor.exportAsPNG() // Works: conformance is MainActor-isolated
}
}
```
### Usage Rules for IsolaRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.