| name | swift6-strict-concurrency |
| description | This skill should be used when the user asks to "migrate to Swift 6",
"enable strict concurrency", "fix Sendable errors", "add @MainActor",
"resolve data race warnings", "implement actor isolation",
"configure complete concurrency checking", "fix Swift 6 warnings",
"make class Sendable", "handle @Sendable closures",
"Swift 6 に移行", "Strict Concurrency を有効化", "Sendable エラーを修正",
"@MainActor を追加", "データ競合警告を解決", "アクター分離を実装",
"完全な並行性チェックを設定", "Swift 6 警告を修正",
"クラスを Sendable にする", "@Sendable クロージャを扱う",
or needs guidance on Swift 6 strict concurrency migration,
Sendable protocol implementation, actor isolation patterns,
data race safety, and migration strategies from Swift 5 to Swift 6.
|
| version | 1.0.0 |
Swift 6 Strict Concurrency
Swift 6 の Strict Concurrency モードへの移行・対応を支援するスキル。Sendable プロトコル、Actor 分離、データ競合の安全性などを網羅的にカバーする。
Overview
Target Platform: iOS 17+ / macOS 14+ / Swift 6.0+
主要な変更点:
- Complete concurrency checking がデフォルトで有効
- すべての型がデータ競合に対して安全であることを保証
- Sendable プロトコルによる型安全な境界定義
- Actor isolation による排他的アクセス制御
Core Concepts:
- Sendable Protocol
- Actor Isolation (@MainActor, custom actors)
- @Sendable Closures
- Data Race Safety
Quick Start Checklist
Swift 6 Strict Concurrency を有効化する手順:
-
Xcode Build Settings で設定
SWIFT_STRICT_CONCURRENCY = complete
-
または Package.swift で設定
.target(
name: "MyTarget",
swiftSettings: [
.swiftLanguageMode(.v6)
]
)
-
段階的に有効化(推奨)
minimal → targeted → complete の順で警告を解消
-
主要なエラーを修正
- 非 Sendable 型のキャプチャ
- Actor 境界を越えるデータアクセス
- @MainActor の不足
Xcode Project Configuration
Build Settings
| 設定 | 値 | 説明 |
|---|
SWIFT_STRICT_CONCURRENCY | minimal | 最小限の警告(デフォルト) |
SWIFT_STRICT_CONCURRENCY | targeted | @Sendable を明示した部分のみ |
SWIFT_STRICT_CONCURRENCY | complete | 完全なデータ競合チェック |
Package.swift
let package = Package(
name: "MyPackage",
platforms: [.iOS(.v17), .macOS(.v14)],
targets: [
.target(
name: "MyTarget",
swiftSettings: [
.swiftLanguageMode(.v6)
]
)
]
)
.target(
name: "MyTarget",
swiftSettings: [
.enableUpcomingFeature("StrictConcurrency")
]
)
詳細は references/xcode-configuration.md を参照。
Sendable Protocol
自動準拠する型
以下の型は自動的に Sendable に準拠:
- 値型(struct/enum): すべてのプロパティが Sendable の場合
- Actor: 常に Sendable
- 基本型: Int, String, Bool, etc.
struct UserData: Sendable {
let id: UUID
let name: String
}
enum Status: Sendable {
case pending
case completed(Date)
}
手動準拠(Reference Types)
final class Config: Sendable {
let apiKey: String
let timeout: TimeInterval
init(apiKey: String, timeout: TimeInterval) {
self.apiKey = apiKey
self.timeout = timeout
}
}
@unchecked Sendable
内部で同期処理を行う場合に使用(慎重に):
final class ThreadSafeCache: @unchecked Sendable {
private let lock = NSLock()
private var storage: [String: Data] = [:]
func get(_ key: String) -> Data? {
lock.lock()
defer { lock.unlock() }
return storage[key]
}
func set(_ key: String, value: Data) {
lock.lock()
defer { lock.unlock() }
storage[key] = value
}
}
詳細は references/sendable-guide.md を参照。
Actor Isolation
@MainActor
UI 更新を行うクラスに適用:
@Observable
@MainActor
class ViewModel {
var items: [Item] = []
var isLoading = false
var errorMessage: String?
func loadData() async {
isLoading = true
defer { isLoading = false }
do {
items = try await api.fetchItems()
} catch {
errorMessage = error.localizedDescription
}
}
}
Custom Actor
データの排他的アクセスが必要な場合:
actor ImageCache {
private var cache: [URL: UIImage] = [:]
func image(for url: URL) -> UIImage? {
cache[url]
}
func setImage(_ image: UIImage, for url: URL) {
cache[url] = image
}
func clear() {
cache.removeAll()
}
}
let cache = ImageCache()
let image = await cache.image(for: url)
nonisolated
Actor 内で同期アクセスを許可:
actor DataManager {
let id: String
nonisolated var identifier: String {
id
}
nonisolated func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
詳細は references/actor-isolation.md を参照。
@Sendable Closures
基本的な使用法
Task {
await performWork()
}
func performAsync(_ work: @Sendable @escaping () async -> Void) {
Task { await work() }
}
キャプチャリストの注意点
@MainActor
class ViewModel {
var count = 0
func increment() {
Task.detached {
self.count += 1
}
Task {
self.count += 1
}
}
}
詳細は examples/sendable-closures.swift を参照。
Common Errors and Fixes
| エラーメッセージ | 原因 | 解決策 |
|---|
Capture of 'x' with non-sendable type in @Sendable closure | 非 Sendable 型をクロージャでキャプチャ | Sendable に準拠させるか actor を使用 |
Call to main actor-isolated method in synchronous nonisolated context | @MainActor メソッドを非分離コンテキストから呼び出し | await を追加、または呼び出し元も @MainActor に |
Stored property 'x' of 'Sendable'-conforming class must be immutable | Sendable クラスに var プロパティ | let に変更、または actor を使用 |
Actor-isolated property 'x' cannot be mutated from a non-isolated context | アクター外からプロパティを変更 | await を使用してアクターメソッド経由で変更 |
Non-sendable type 'X' cannot cross actor boundary | 非 Sendable 型をアクター境界で渡す | Sendable に準拠させる |
Task-isolated value of type 'X' passed as a strongly transferred parameter | Task 間でのデータ転送 | Sendable に準拠させるか、コピーを渡す |
詳細は references/common-errors.md を参照。
Migration Strategy
段階的移行アプローチ
-
Phase 1: 現状把握
bash scripts/swift6-migration-analyzer.sh /path/to/project
-
Phase 2: targeted で有効化
SWIFT_STRICT_CONCURRENCY = targeted に設定
- 明示的に @Sendable をマークした箇所のみ警告
-
Phase 3: 主要な型を修正
- ViewModel → @MainActor を追加
- 共有データ → actor に変換
- 不変データ → Sendable に準拠
-
Phase 4: complete で有効化
SWIFT_STRICT_CONCURRENCY = complete に設定
- すべての警告を解消
-
Phase 5: Swift 6 に移行
.swiftLanguageMode(.v6) を設定
Before/After 例
class ViewModel: ObservableObject {
@Published var items: [Item] = []
func load() {
Task {
items = try await api.fetch()
}
}
}
@Observable
@MainActor
class ViewModel {
var items: [Item] = []
func load() async {
items = try await api.fetch()
}
}
詳細は references/migration-checklist.md を参照。
Additional Resources
Example Files
Reference Files
Utility Scripts