swift_concurrency

Swift modern concurrency with async/await, Task, Actor, Swift 6 strict mode, Sendable, and structured concurrency patterns.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "swift_concurrency" with this command: npx skills add swiftzilla/skills/swiftzilla-skills-swift-concurrency

Swift Concurrency

This skill covers Swift's modern concurrency features from Swift 5.5 through Swift 6, including async/await, structured concurrency, actors, and Swift 6's strict data-race safety.

Overview

Swift's modern concurrency model provides a safer, more intuitive way to write asynchronous code. Swift 6 takes this further with compile-time data-race safety, turning potential concurrency bugs into compiler errors.

Available References

Swift 6 & Strict Concurrency

Core Concurrency

  • Async/Await - Asynchronous functions, Task, TaskGroup, Actor basics

Swift 6 Highlights

Strict Concurrency by Default

Swift 6 enforces data-race safety at compile time:

// ❌ Compile-time error in Swift 6
var globalCounter = 0

func increment() {
    globalCounter += 1  // Error: concurrent access
}

// ✅ Safe with actor isolation
actor Counter {
    private var value = 0
    func increment() { value += 1 }
}

Sendable Protocol

Mark types safe to share across concurrency boundaries:

struct User: Sendable {
    let id: Int
    let name: String
}

@Sendable func process() async {
    // Captures must be Sendable
}

MainActor & Global Actors

@MainActor
class ViewModel: ObservableObject {
    @Published var items = [Item]()
}

@globalActor
actor DatabaseActor {
    static let shared = DatabaseActor()
    private init() {}
}

Quick Reference

Async/Await Basics

func fetchData() async throws -> Data {
    let (data, _) = try await URLSession.shared.data(from: url)
    return data
}

Swift 6 Migration Checklist

  • Enable Swift 6 language mode
  • Enable strict concurrency checking
  • Wrap global mutable state in actors
  • Add Sendable conformance to types
  • Fix non-Sendable captures in @Sendable closures
  • Isolate UI code with @MainActor
  • Audit third-party dependencies

Running Async Code

// Fire-and-forget
Task {
    let result = await asyncOperation()
}

// With priority
Task(priority: .background) {
    await heavyComputation()
}

// With cancellation
let task = Task {
    try await longRunningOperation()
}
task.cancel()

Concurrent Operations

// Async let (parallel await)
async let task1 = fetchUser()
async let task2 = fetchSettings()
let (user, settings) = try await (task1, task2)

// TaskGroup
try await withThrowingTaskGroup(of: Item.self) { group in
    for id in ids {
        group.addTask { try await fetchItem(id: id) }
    }
    return try await group.reduce(into: []) { $0.append($1) }
}

Actor Thread Safety

actor BankAccount {
    private var balance: Double = 0
    
    func deposit(_ amount: Double) {
        balance += amount
    }
    
    func getBalance() -> Double {
        return balance
    }
}

let account = BankAccount()
await account.deposit(100)

Isolation Boundaries

// Crossing isolation boundaries
@MainActor
func updateUI() async {
    // On main thread
    let data = await fetchData()  // Switch to non-isolated
    label.text = data  // Back to main thread
}

// Region transfer
func process() async {
    let data = Data()  // Disconnected
    await save(data)   // Transfer to actor
    // ❌ Can't use data here anymore
}

Swift 6 vs Swift 5.x

FeatureSwift 5.xSwift 6
Concurrency checkingWarningsErrors
Data race safetyRuntimeCompile-time
Sendable enforcementOpt-inRequired
Global variable safetyWarningError
Strict modeExperimentalDefault

Best Practices

Swift 6 Best Practices

  1. Enable Swift 6 mode early - Start migration now
  2. Use actors for shared state - Default to actors over locks
  3. Design Sendable types - Make types Sendable from the start
  4. Isolate UI with @MainActor - All UI code on main thread
  5. Respect isolation regions - Don't use values after transfer
  6. Leverage compile-time safety - Let compiler catch data races
  7. Create domain actors - Custom global actors for heavy work

General Concurrency

  1. Prefer async/await - Over completion handlers
  2. Use structured concurrency - Clear task hierarchies
  3. Handle cancellation - Check Task.isCancelled
  4. Use value types - Immutable data is thread-safe
  5. Avoid shared mutable state - Or protect with actors

Migration from Completion Handlers

// Before (Swift 5)
func fetchUser(completion: @escaping (Result<User, Error>) -> Void) {
    URLSession.shared.dataTask(with: url) { data, response, error in
        // Handle result
        completion(result)
    }.resume()
}

// After (Swift 6)
func fetchUser() async throws -> User {
    let (data, _) = try await URLSession.shared.data(from: url)
    return try JSONDecoder().decode(User.self, from: data)
}

Common Swift 6 Errors

ErrorQuick Fix
Concurrent access to globalWrap in actor
Non-Sendable in @SendableMake type Sendable
Actor isolation violationAdd await or change isolation
Use after transferUse before transfer or copy value
Main actor isolationAdd @MainActor annotation

Resources

For More Information

Each reference file contains detailed information, code examples, and best practices for specific topics. Visit https://swiftzilla.dev for comprehensive Swift concurrency documentation.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

swift_swiftui

No summary provided by upstream source.

Repository SourceNeeds Review
General

swift_style

No summary provided by upstream source.

Repository SourceNeeds Review
General

swift_combine

No summary provided by upstream source.

Repository SourceNeeds Review
General

swift_structure

No summary provided by upstream source.

Repository SourceNeeds Review