Loading...
Loading...
Swift modern concurrency with async/await, Task, Actor, Swift 6 strict mode, Sendable, and structured concurrency patterns.
npx skill4agent add swiftzilla/skills swift_concurrency// ❌ 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 }
}struct User: Sendable {
let id: Int
let name: String
}
@Sendable func process() async {
// Captures must be Sendable
}@MainActor
class ViewModel: ObservableObject {
@Published var items = [Item]()
}
@globalActor
actor DatabaseActor {
static let shared = DatabaseActor()
private init() {}
}func fetchData() async throws -> Data {
let (data, _) = try await URLSession.shared.data(from: url)
return data
}// 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()// 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 BankAccount {
private var balance: Double = 0
func deposit(_ amount: Double) {
balance += amount
}
func getBalance() -> Double {
return balance
}
}
let account = BankAccount()
await account.deposit(100)// 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
}| Feature | Swift 5.x | Swift 6 |
|---|---|---|
| Concurrency checking | Warnings | Errors |
| Data race safety | Runtime | Compile-time |
| Sendable enforcement | Opt-in | Required |
| Global variable safety | Warning | Error |
| Strict mode | Experimental | Default |
// 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)
}| Error | Quick Fix |
|---|---|
| Concurrent access to global | Wrap in actor |
| Non-Sendable in @Sendable | Make type Sendable |
| Actor isolation violation | Add await or change isolation |
| Use after transfer | Use before transfer or copy value |
| Main actor isolation | Add @MainActor annotation |