swift-concurrency
SKILL.md
Swift Concurrency Best Practices (Swift 6+)
1. Structured Concurrency
- Prefer
async letfor parallel tasks when the number of tasks is known. - Use
TaskGroupfor a dynamic number of parallel tasks. - Avoid
Task { ... }(unstructured) unless bridging from synchronous code (e.g., UI event handlers) or firing background work that outlives the scope.
2. Actors & Isolation
- Default to
@MainActorfor all UI-related classes (ViewModels, SwiftUI Views). - Use
actorfor shared mutable state that is not UI-related (e.g., caching, database managers). - Global Actors: Use
@MainActoror custom global actors to synchronize access across different types.
3. Sendability
- Strict Concurrency Checking: Assume
Strict Concurrencyis ON. - Mark immutable structs/enums as
Sendable(often implicit, but be explicit if public). - For classes, use
finaland@unchecked Sendableonly if you are manually managing thread safety (locks/queues). Ideally, useactor. - Closures: Ensure closures passed between contexts are
@Sendable.
4. Migration from Combine/Closures
- Replace
DispatchQueue.main.asyncwithawait MainActor.run { ... }or isolate the function itself. - Replace
Future/Promisewith directasync throwsfunctions. - Use
AsyncStreamto replace simple CombinePassthroughSubjectscenarios.
Example: Safe ViewModel
@MainActor
final class UserViewModel: ObservableObject {
@Published var users: [User] = []
// Dependencies should be Sendable
private let client: APIClient
func load() async {
do {
// 'await' suspends, allowing other work on MainActor if needed
self.users = try await client.fetchUsers()
} catch {
print(error)
}
}
}
Weekly Installs
9
Repository
tryswift/try-swift-tokyoGitHub Stars
187
First Seen
Feb 28, 2026
Security Audits
Installed on
opencode9
gemini-cli9
codebuddy9
github-copilot9
codex9
kimi-cli9