WWDC.ai

What's new in Swift

Swift 6.3 and 6.4 add everyday language cleanup, stronger testing and subprocess APIs, broader interoperability, and safer performance tuning.

Watch on Apple Developer

TL;DR

  • Swift 6.4 reduces boilerplate with optional some/any syntax cleanup, anyAppleOS availability, @diagnose, weak let, explicit ~Sendable, and more accessible memberwise initializers.
  • Library updates include task cancellation shields, Dictionary.mapKeyedValues, a standard-library FilePath, Swift Testing severity/cancellation/XCTest interop, Subprocess 1.0, and Foundation ProgressManager.
  • Swift expands beyond Apple platforms with @C exports, improved Swift-Java and Android SDK support, VSCode/OpenVSX tooling, WebAssembly/JavascriptKit improvements, and a larger Embedded Swift subset.
  • Performance work focuses on explicit optimizer control with @inline(always) and @specialized, plus ownership features such as Iterable, borrow/mutate accessors, UniqueBox, UniqueArray, Ref, and MutableRef.

Everyday Swift language improvements

Swift 6.3 and 6.4 focus heavily on making intent clearer with less boilerplate. Swift 6.4 removes the need to parenthesize some or any when used with optional types, warns when a throwing Task error is silently ignored, and removes the old restriction on calling async functions from defer.

Concurrency and access-control ergonomics also improve: immutable weak references can be written as weak let, types can explicitly opt out of Sendable with ~Sendable, and structs that mix internal and private stored properties now receive a usable internal memberwise initializer in addition to the private full initializer.

  • Use anyAppleOS to consolidate matching availability across Apple platforms, with platform-specific carve-outs when needed.
  • Use #if os(anyAppleOS) for conditional compilation across Apple OSes.
  • Use @diagnose to ignore, enable, warn, or error specific diagnostic groups inside one declaration.
  • Use module selectors, written Module::name, when imported modules contain conflicting type, method, or property names.

Condense Apple-platform availability with anyAppleOS

anyAppleOS replaces repeated macOS/iOS/watchOS/tvOS/visionOS availability when the versioning aligns.

extension Mission {
  @available(anyAppleOS 27, *)
  func showStatus() { ... }

  @available(anyAppleOS 27, *)
  @available(tvOS, unavailable)
  func launch() { ... }

  #if os(anyAppleOS)
  func makeLiveActivityWidget() -> some Widget { ... }
  #endif
}

Resolve module name conflicts with ::

The left side of :: is always treated as a module name, avoiding ambiguity with same-named types or extension members.

import Rocket
import GiftShopToys

let rocket = Rocket::SaturnV()
launchPadTechnician.HumanResources::fire()

Control diagnostics locally

@diagnose lets a declaration suppress, enable, or promote selected diagnostic groups without changing the whole project.

@diagnose(DeprecatedDeclaration, as: ignored, reason: "Temporary migration")
func makeLegacyMission() -> Mission { ... }

@diagnose(StrictMemorySafety, as: warning)
func uplinkCommand(...) { ... }

@diagnose(ErrorInFutureSwiftVersion, as: error)
func fetchPosition() -> (x: Double, y: Double, z: Double) { ... }

Standard library, testing, Subprocess, and Foundation

The standard library adds targeted APIs for common correctness and portability problems. A task cancellation shield allows a short critical section to finish or roll back work even if the surrounding task is cancelled. mapKeyedValues transforms dictionary values while also receiving each key, and the standard-library FilePath brings cross-platform path manipulation from Swift System into everyday Swift.

Swift Testing in Swift 6.4 gains more control over test outcomes. Issue.record can report warnings that do not fail CI, Test.cancel can dynamically cancel individual cases in parameterized tests, and swift test can repeat tests until pass or fail with a maximum repetition count. XCTest and Swift Testing now interoperate in both directions, with interoperability issues reported as warnings by default and promotable to failures in Xcode build settings.

Subprocess 1.0 refines process execution with simpler execution types, improved errors, output streaming through AsyncBufferSequence, line-by-line strings() reading that respects grapheme cluster boundaries, and better cross-platform process semantics. Foundation adds ProgressManager for async-aware progress composition and reporting, while Swift-Foundation continues migrating implementation to Swift with faster Data, NSURL, and CFURL behavior.

Use a task cancellation shield for short critical work

Inside the shield, cancellation checks return false; keep the shielded region short and limited to finishing or rolling back started work.

extension EmergencyTransponder {
  func sendSOS() {
    withTaskCancellationShield {
      radio.send(makeSOSPacket())
    }
  }
}

Transform dictionary values with access to keys

mapKeyedValues avoids manually rebuilding a dictionary when the new value depends on both key and old value.

func makeCalendarDisplayNames(for missions: [Mission: LaunchWindow]) -> [Mission: String] {
  missions.mapKeyedValues { mission, launchWindow in
    makeDisplayName(for: mission, in: launchWindow)
  }
}

Record warnings and dynamically cancel Swift Testing cases

Swift Testing can now distinguish non-fatal warnings from failing expectations and cancel cases at runtime.

@Test(arguments: allRockets)
func testBurn(rocket: Rocket) throws {
  if rocket.engineType == .solid {
    try Test.cancel("\(rocket.name) has solid fuel")
  }

  rocket.burn(for: .seconds(150))
  let remaining = rocket.propellantKg / rocket.totalPropellantKg
  if remaining < 0.10 {
    Issue.record("Remaining fuel below reserve target", severity: .warning)
  }
  #expect(remaining > 0.02, "Propellant critically low - abort")
}

Interoperability and Swift beyond Apple platforms

Swift 6.4 extends language interoperability so Swift can be adopted incrementally in existing systems. The new @C attribute exposes Swift functions to C for C-compatible types, and @implementation can be used when implementing an existing C declaration in Swift. Safe interop features translate array-and-count style C APIs into safer Swift spans, and C++20 spans also bridge with Swift spans.

Swift-Java now supports calling async and throwing Swift functions from Java, captures more of Swift generics including constrained extensions, and can conform Java classes to Swift protocols. This improves Swift use from Java and Kotlin, including on Android, where an official Swift SDK is available from swift.org.

Tooling expands as well: the Swift VSCode extension integrates with Swiftly for installing toolchains from swift.org and is available on OpenVSX for editors such as VSCodium, Cursor, Kiro, and Antigravity. Swift can also compile to WebAssembly, and JavascriptKit has improved safer Swift-to-JavaScript bridging; the session cites Goodnotes benchmarks showing safe bridging 35-40x faster than the older dynamic bridging path.

  • Use @C only with C-compatible signatures; the compiler prevents incompatible Swift-only types from being exported.
  • Use @implementation when the C declaration already exists and Swift is providing the implementation.
  • Use generated C interop headers when Swift introduces a new exported C-callable function.
  • Use Swiftly-enabled editor tooling to install the right open-source toolchain for targets such as WebAssembly or embedded platforms.

Swift-to-C export workflow

The session demonstrates replacing C launch-window functions with Swift implementations using @C; existing C declarations use @implementation, while new Swift functions are emitted into the generated C interop header.

Embedded Swift and constrained environments

Embedded Swift continues to grow while remaining a subset of the full language. Swift 6.4 adds support for existential types, allowing values of multiple conforming types to be stored or passed through protocol-typed APIs in embedded contexts. It also adds untyped throws using the same underlying machinery that supports existentials.

Debuggability improves without increasing runtime binary size. Embedded Swift stores type-layout metadata needed by the debugger in DWARF debug info, which improves coredump debugging on constrained hardware where a live process may not be available.

Diagnostics in the EmbeddedRestrictions warning group identify language features unavailable in embedded contexts. For libraries that support both full and embedded Swift, @diagnose can tune these diagnostics on specific declarations.

Use @diagnose with embedded restrictions

The exact policy depends on the library, but @diagnose is the mechanism discussed for controlling embedded-restriction diagnostics locally.

@diagnose(EmbeddedRestrictions, as: warning)
func fullSwiftOnlyEntryPoint() { ... }

Performance tuning with optimizer control and ownership

Swift's optimizer normally decides when code duplication is worth it, but Swift 6.3 and 6.4 add explicit controls for performance-sensitive code. @inline(always) complements the existing @inline(never) by forcing inlining when possible; for class methods, final may be needed because dynamically dispatched methods cannot always be inlined. @specialized asks the compiler to generate a concrete implementation of a generic function for important type constraints.

The larger performance theme is avoiding unnecessary copies without falling back to unsafe pointers. Swift's ownership model represents safe shared read access as borrows and safe exclusive write access as mutations, with compile-time exclusivity checking. Swift 6.4 extends more protocols and generic patterns into this world: Equatable, Comparable, and Hashable work with noncopyable types, Equatable and Comparable also work with non-escapable types, and associated types can be ~Copyable or ~Escapable.

The new Iterable protocol lets for loops borrow elements instead of copying them out, which supports noncopyable elements and can avoid reference-counting costs for object and copy-on-write values. New borrow and mutate accessors let computed properties provide read-only shared access or exclusive in-place mutation without copying. The standard library also adds UniqueBox, UniqueArray, Continuation, Ref, and MutableRef for safe high-performance ownership patterns.

  • Prefer straightforward Swift first; these features are intended for hot paths, libraries, embedded code, or other constrained environments.
  • Use @inline(always) and @specialized selectively because they can increase code size and may hurt performance if overused.
  • Iterable is used by for loops when Sequence is unavailable; if both exist, Sequence is preferred because mutation/exclusivity behavior differs.
  • Ref and MutableRef are non-escapable, allowing Swift to know when the borrowed or mutable access ends.

Request optimizer decisions explicitly

@inline(always) forces inlining when possible, while @specialized generates a concrete generic specialization for important call patterns.

@inline(always)
func makeInts(randomized: Bool) -> [256 of Int] { ... }

@specialized(where Values == [UInt8])
func histogram<Values>(of values: Values) -> [256 of Int]
where Values: Sequence<UInt8> { ... }

Use borrow and mutate accessors to avoid copies

The property can expose storage for read or in-place mutation without copying a large or noncopyable value through get and set.

@safe public struct UniqueBox<Value: ~Copyable>: ~Copyable {
  private let valuePointer: UnsafeMutablePointer<Value>

  public var value: Value {
    borrow { valuePointer.pointee }
    mutate { &valuePointer.pointee }
  }
}

Hoist repeated dictionary access with MutableRef

MutableRef keeps a mutable access open across the loop, avoiding repeated dictionary lookups without an unsafe pointer or helper inout trick.

func updateCount<Key: Hashable>(for key: Key, from sets: [Set<Key>], in counts: inout [Key: Int]) {
  var countRef = MutableRef(&counts[key, default: 0])
  for set in sets {
    if set.contains(key) {
      countRef.value += 1
    }
  }
}

Open-source Swift ecosystem direction

The session closes by emphasizing that these features are developed in open source across Apple OSes, Linux, Windows, Android, and other environments. Swift Build, the build system from Xcode, is now the default build-system backend for Swift Package Manager, improving consistency between package builds and Xcode builds.

New and continuing workgroups include build and packaging, networking, Windows, and Android. The Android workgroup released the first Swift SDK for Android as part of Swift 6.3, enabling shared Swift code between Android and iOS apps. Developers are encouraged to follow and participate through the Swift Forums.

Resources

Unofficial, not associated with Apple. BySuperwall

On this page

Ask AI