Skip to content

Fix Xcode 27 beta build errors#1038

Merged
pblazej merged 4 commits into
mainfrom
blaze/xcode-27-beta
Jun 10, 2026
Merged

Fix Xcode 27 beta build errors#1038
pblazej merged 4 commits into
mainfrom
blaze/xcode-27-beta

Conversation

@pblazej

@pblazej pblazej commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes the Xcode 27 beta (macOS 27 / iOS 27 SDK) build failures reported in #1035 and #1037. Behavior is preserved on every OS and toolchain — there is no macOS 12.x regression.

Root cause

These are SDK-side annotation changes that only the Swift importer enforces as hard errors — the underlying APIs still exist on the OS versions they always shipped in:

  • Xcode 27 beta build errors (macOS) #1035AVAudioNode.auAudioUnit: gained NS_REFINED_FOR_SWIFT; its new Swift overlay is introduced: macOS 13.0, deprecated: 27.0 (in favor of withAUAudioUnit). The Objective-C property is still macos(10.13).
  • Xcode 27 beta build errors (macOS) #1035SCStreamConfiguration.width/height: re-annotated from the class-inherited macos(12.3) to an explicit macos(13.0) when Apple extended ScreenCaptureKit to iOS/tvOS 27.
  • Xcode 27 Beta deprecation error #1037RPBroadcastSampleHandler: deprecated in the iOS 27 SDK (ios(10.0, 27.0)). Xcode 27 builds the LKObjCHelpers .pcm with -clang-target …ios27.0, so the deprecation fires and -Werror fails the module. (Requires that clang-target + "treat warnings as errors", which is why it doesn't reproduce on a default build.)

Changes

  • Audio (auAudioUnit): new AVAudioNode.maximumFramesToRender extension that centralizes access; call sites (PlayerNodePool, SoundPlayer, MixerEngineObserver) just use node.maximumFramesToRender. It resolves per toolchain/OS:
    • Xcode 26 (compiler < 6.4): the auAudioUnit property directly — unchanged.
    • Xcode 27, OS 27+: withAUAudioUnit { … }, the non-deprecated replacement Apple points to.
    • Xcode 27, macOS 13–26: the auAudioUnit property (available and not yet deprecated there).
    • Xcode 27, below macOS 13: LKObjCHelpers, where the original ObjC availability (macos(10.13)) still applies — so full behavior is preserved with no regression.
  • Screen capture (width/height): #if compiler(>=6.4)LKObjCHelpers.setWidth(…) (Xcode 27, preserves full capture resolution on macOS 12.x); #else → native configuration.width/height (Xcode 26 stays idiomatic).
  • Xcode 27 Beta deprecation error #1037: -Wdeprecated-declarations pragma around the finishBroadcastWithoutError: declaration so the precompiled module emits.
  • Reverts the macOS exclusion from Exclude macOS from buffer size workaround #1034 (ae0d2fb): maximumFramesToRender matching runs on macOS again via the extension, so the #if os(iOS) || os(visionOS) || os(tvOS) once more wraps only the iOS audio-session logging.
  • Build warnings: silenced pre-existing warnings the newer toolchain/SDK surfaces — BroadcastUploader's bare Task { try await … }Task.discarding; the retroactive AudioStreamBasicDescription: Codable conformance qualified as Swift.Codable (matching the Sendable.swift convention); and kIOMasterPortDefault → guarded kIOMainPortDefault in Utils. The build is now warning-free apart from the unrelated E2EEOptions deprecation.

Note: #if compiler(>=6.4) (toolchain version), not #if swift(>=6.4) (language version) — the latter is false under CocoaPods (swift_versions ["5.9"]) on Xcode 27 and would take the wrong path.

Testing

Built locally against Xcode 27 beta (27A5194q, Swift 6.4) and Xcode 26.5 (Swift 6.3.2):

  • Xcode 27: macOS, iOS, tvOS, Mac Catalyst, visionOS — ✅
  • Xcode 26.5: macOS, iOS — ✅
  • 0 non-deprecation warnings on every platform/toolchain; swiftformat clean

Closes #1035
Closes #1037

🤖 Generated with Claude Code

The macOS 27 / iOS 27 SDKs re-annotate several APIs with higher
availability than the OS versions they actually ship in, which the Swift
importer enforces as hard errors:

- AVAudioNode.auAudioUnit: the Swift overlay is now introduced macOS 13.0
  (the Objective-C property is still macos(10.13))
- SCStreamConfiguration.width/height: bumped from macos(12.3) to macos(13.0)
- RPBroadcastSampleHandler: deprecated in iOS 27, which breaks the
  LKObjCHelpers precompiled module under -Werror

Route AVAudioNode.maximumFramesToRender through LKObjCHelpers via an
extension, where the original ObjC availability still applies, so it works
on every SDK/OS version with no version check and no behavior change.
Screen capture sets width/height through the same helper on Xcode 27
(#if compiler(>=6.4)) and directly on older toolchains. Also restores the
macOS maximumFramesToRender matching that #1034 had to drop.

Closes #1035
Closes #1037

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@pblazej pblazej force-pushed the blaze/xcode-27-beta branch from c6124cb to 598ebb1 Compare June 10, 2026 08:59
On the Xcode 27 SDK, use the non-deprecated withAUAudioUnit
(macOS/iOS/tvOS/visionOS 27+) and fall back to the LKObjCHelpers ObjC
workaround only on earlier OSes. Toolchains before Swift 6.4 keep the
direct auAudioUnit property.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@pblazej pblazej marked this pull request as ready for review June 10, 2026 09:55
/// which keeps the property's original Objective-C availability (macOS 10.13). See #1035.
var maximumFramesToRender: AUAudioFrameCount {
get {
#if compiler(>=6.4)

@pblazej pblazej Jun 10, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a little overengineered vs e.g.

if #available(macOS 13.0, *) {
  return auAudioUnit.maximumFramesToRender
}
return LKObjCHelpers.maximumFramesToRender(for: self)

which would surface the deprecation on 27.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May change in the upcoming betas tho...

- BroadcastUploader: bare `Task { try await … }` → `Task.discarding`
  (#NoUseUnstructuredThrowingTask is active under Swift 6.4)
- BroadcastAudioCodec: qualify the retroactive `AudioStreamBasicDescription`
  `Codable` conformance as `Swift.Codable`, matching the `Sendable.swift`
  convention for suppressing the imported-conformance warning
- Utils.modelIdentifier: `kIOMasterPortDefault` → `kIOMainPortDefault`,
  guarded with the NULL default port (0) before macOS 12

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@pblazej pblazej force-pushed the blaze/xcode-27-beta branch from 669593d to d0afa8b Compare June 10, 2026 10:21
Narrows the LKObjCHelpers fallback to macOS < 13: withAUAudioUnit on
OS 27+, the auAudioUnit property on macOS 13–26 (available and not yet
deprecated there), and the ObjC shim only below macOS 13.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@pblazej pblazej merged commit d809c78 into main Jun 10, 2026
18 of 23 checks passed
@pblazej pblazej deleted the blaze/xcode-27-beta branch June 10, 2026 10:48
pblazej added a commit that referenced this pull request Jun 10, 2026
## Summary

Follow-up to #1038. The nightly **Swift Snapshot Build**
(`.github/workflows/swift-snapshot.yaml`) fails on `main` after #1038:

```
Sources/LiveKit/Extensions/AVAudioNode.swift:34:24: error: cannot find 'withAUAudioUnit' in scope
```

## Root cause

That workflow runs `swift build` with the **main-snapshot** compiler (so
`#if compiler(>=6.4)` is true) but against the runner's **current stable
SDK** (macOS 26 — `latest` Xcode, since 27 is still beta).
`withAUAudioUnit` only exists in the **macOS 27 SDK**, so the
`compiler(>=6.4)` branch compiles the symbol in, but the SDK doesn't
have it.

The deeper issue: `#if compiler(>=6.4)` is a *compiler* check used as an
*SDK* proxy. That holds for shipping Xcode (compiler and SDK ship
together) but not for the snapshot toolchain (new compiler + stable
SDK). There's no reliable compile-time SDK/API-presence check in Swift —
`canImport(AVFAudio, _version:)` reports the same version in both SDKs,
and keying off a new-in-27 framework would be fragile.

## Fix

Drop `withAUAudioUnit` and reach `auAudioUnit` — which exists on
**every** SDK (only its Swift availability annotation differs) — under
`if #available(macOS 13.0)`, falling back to `LKObjCHelpers` below macOS
13. `#if compiler(>=6.4)` is kept so older toolchains (Xcode 16.4 /
26.5) use the property directly with no ObjC shim down to macOS 10.13.

This compiles on every compiler/SDK combination, including the
snapshot's newer-compiler + macOS 26 SDK.

## Testing

- `swift build --build-system native` with the Xcode 27 compiler **+
macОS 26 SDK** (reproduces the snapshot combo): **Build complete** ✅
(was: `cannot find 'withAUAudioUnit'`).
- Xcode 27 (macOS/iOS) and Xcode 26.5 (macOS) builds: ✅
- swiftformat clean.

No user-facing behavior change (the `auAudioUnit` access is functionally
identical), so no changeset.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Xcode 27 Beta deprecation error Xcode 27 beta build errors (macOS)

2 participants