The Swift language mode, strict concurrency checking, and default actor isolation are separate configurations. Changing one does not automatically change the others.
Configuration landscape
| Setting | Controls |
|---|---|
SWIFT_VERSION | Swift language mode and associated concurrency rules. |
SWIFT_STRICT_CONCURRENCY | Concurrency diagnostics in Swift 5 language mode. |
SWIFT_DEFAULT_ACTOR_ISOLATION | Default isolation for otherwise unannotated declarations. |
SWIFT_APPROACHABLE_CONCURRENCY | A group of Swift 6.2 migration features. |
SWIFT_UPCOMING_FEATURE_* | Individual upcoming language features. |
Swift language mode
Xcode: Swift Language Version · Build setting: SWIFT_VERSION
| Value | Behavior |
|---|---|
5 | Swift 5 compatibility, including when using a Swift 6 compiler. |
6 | Swift 6 rules, including strict data-race safety checking. |
Swift 5 mode still supports actors, async/await, task groups, and Sendable. Violations that warn in Swift 5 can become errors in Swift 6.
SWIFT_VERSION = 5
SWIFT_STRICT_CONCURRENCY = completeStrict concurrency checking
Xcode: Strict Concurrency Checking · Build setting: SWIFT_STRICT_CONCURRENCY
| Value | Meaning |
|---|---|
minimal | Limited checking around explicit concurrency annotations. |
targeted | Additional checking in code adopting concurrency features. |
complete | Full checking, including code not explicitly using concurrency. |
Complete checking is primarily a Swift 5 migration setting. Swift 6 language mode enforces complete checking regardless of this value.
SWIFT_VERSION = 5
SWIFT_STRICT_CONCURRENCY = completeDefault actor isolation
Available in Swift 6.2+. Build setting: SWIFT_DEFAULT_ACTOR_ISOLATION
| Value | Meaning |
|---|---|
nonisolated | Declarations are nonisolated unless explicitly isolated or inferred. |
MainActor | Unannotated declarations default to main-actor isolation. |
class ProfileViewModel {
var name = ""
func updateName(_ value: String) {
name = value
}
}nonisolated struct UserDTO: Codable, Sendable {
let id: UUID
let name: String
}MainActor suits a primarily SwiftUI app target. nonisolated is often a better default for reusable non-UI packages. Default main-actor isolation does not make every operation run on the main actor.
Approachable Concurrency
Available in Swift 6.2+. This bundle groups features that make migration more incremental.
SWIFT_APPROACHABLE_CONCURRENCY = YES| Feature | Purpose |
|---|---|
DisableOutwardActorInference | Limits implicit propagation of global-actor isolation. |
GlobalActorIsolatedTypesUsability | Improves use of global-actor-isolated types in safe contexts. |
InferIsolatedConformances | Infers actor-isolated protocol conformances where appropriate. |
InferSendableFromCaptures | Improves Sendable inference from captures. |
NonisolatedNonsendingByDefault | Changes how nonisolated async functions inherit caller context. |
Execution context matters
With NonisolatedNonsendingByDefault, marking an async function nonisolated does not necessarily move expensive work off the caller's actor.
nonisolated func process() async {
// Can remain in the caller's isolation context.
}
@concurrent
nonisolated func heavyWork() async {
// Executes on the generic executor.
}@concurrent does not create a new thread per call or make unsafe shared state safe.
Individual upcoming features
Use Xcode's Other Swift Flags to enable one feature without enabling the whole bundle:
-enable-upcoming-feature NonisolatedNonsendingByDefault -enable-upcoming-feature InferIsolatedConformancesSwift Package Manager
Xcode target settings do not automatically configure independently built package targets. Configure package targets explicitly when consistent semantics are required.
swiftSettings: [
.swiftLanguageMode(.v6),
.defaultIsolation(MainActor.self),
.enableUpcomingFeature("NonisolatedNonsendingByDefault"),
.enableUpcomingFeature("InferIsolatedConformances")
]For non-UI packages, omit .defaultIsolation(MainActor.self) or explicitly choose the nonisolated default. The swift-tools-version is the minimum tools version, not the language mode.
Recommended configurations
New SwiftUI application
SWIFT_VERSION = 6
SWIFT_STRICT_CONCURRENCY = complete
SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor
SWIFT_APPROACHABLE_CONCURRENCY = YESUse explicit isolation choices for CPU-intensive and reusable code.
Existing app migrating to Swift 6
SWIFT_VERSION = 5
SWIFT_STRICT_CONCURRENCY = complete
SWIFT_DEFAULT_ACTOR_ISOLATION = nonisolated
SWIFT_APPROACHABLE_CONCURRENCY = NOResolve warnings progressively, then evaluate default isolation and approachable concurrency independently before switching language modes.
Reusable non-UI framework
SWIFT_VERSION = 6
SWIFT_STRICT_CONCURRENCY = complete
SWIFT_DEFAULT_ACTOR_ISOLATION = nonisolated
SWIFT_APPROACHABLE_CONCURRENCY = YESWhat each setting does not do
| Setting or feature | Common misconception |
|---|---|
| Swift 6 language mode | Does not make every declaration main-actor isolated. |
| Strict Concurrency = Complete | Does not change Swift 5 mode into Swift 6 mode. |
| Default Actor Isolation = MainActor | Does not send expensive synchronous work to the background. |
nonisolated | Does not universally mean background execution. |
async | Does not inherently mean parallel execution or a background thread. |
Sendable | Does not schedule work or create actor isolation. |
Version compatibility
| Capability | Swift 5.9–5.10 | Swift 6.0–6.1 | Swift 6.2+ |
|---|---|---|---|
| Swift 5 language mode | Yes | Yes | Yes |
| Swift 6 language mode | No | Yes | Yes |
| Complete strict checking | Opt-in | Automatic in Swift 6 mode | Automatic in Swift 6 mode |
| Default main-actor isolation | No | No | Yes |
| Approachable Concurrency bundle | No | No | Yes |
@concurrent functions | No | No | Yes |