Skip to content

UniFFI: Swift dylibs#1017

Merged
pblazej merged 8 commits intomainfrom
blaze/swift-uniffi-dylib
Apr 17, 2026
Merged

UniFFI: Swift dylibs#1017
pblazej merged 8 commits intomainfrom
blaze/swift-uniffi-dylib

Conversation

@pblazej
Copy link
Copy Markdown
Contributor

@pblazej pblazej commented Apr 15, 2026

Uses this fork: https://github.com/livekit/cargo-swift

  • Leverages proper dylib feature (most of the heavy lifting is in cargo swift)
  • Removes some previous workarounds fixed in the upstream ⬆️

Validated on App Store builds (iOS/macOS):

Screenshot 2026-04-15 at 11 53 32 AM

Running

With system (Xcode) swift: cargo make --profile release swift-package
Using swiftly: swiftly run cargo make --profile release swift-package +6.0

Platforms

Matches this matrix: https://github.com/livekit/webrtc-xcframework#binaries-included

Tiers

These require nightly toolchain:

- aarch64-apple-tvos
- aarch64-apple-tvos-sim
- aarch64-apple-visionos
- aarch64-apple-visionos-sim

x86_64-apple-tvos is permanently tier3 (but not needed, see above Platforms)

Sizes

With the current (unchanged) optimization level, each slice is about 920KB.

RustLiveKitUniFFI.xcframework.zip

pblazej and others added 8 commits April 15, 2026 09:25
…amework

Switch cargo-swift to the livekit fork's framework-wrapping branch and build
the xcframework as a dynamic library wrapped in a .framework bundle so the
package is accepted by App Store Connect. The fork also derives the framework
module name from uniffi.toml, eliminating the post-build sed patches that
renamed headers, modulemaps, and Swift sources to match the xcframework name.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add an Apple privacy manifest at the Swift package root so SPM bundles it
automatically, mirroring the airbnb/lottie-spm distribution. The manifest
declares no tracking or data collection and reports file-timestamp API access
under reason C617.1 (inside app bundle).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy the workspace LICENSE into the generated Swift package alongside
Package.swift so distribution complies with Apache 2.0 redistribution
clause 4(a), matching the airbnb/lottie-spm layout.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rename Package@swift-6.0 to Package@swift-6.2 and require visionOS 26 in the
versioned manifest variant. SPM picks this up only on Swift 6.2+ toolchains;
older toolchains keep falling back to the base Package.swift.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
In addition to shipping the privacy manifest at the Swift package root, copy
it into every per-platform .framework bundle alongside Info.plist (under
Versions/A/Resources for macOS / Mac Catalyst, at the framework root for
shallow slices). This matches Apple's guidance for binary SDK distribution
and mirrors the airbnb/lottie-ios xcframework layout, so the manifest is
present whether the package is consumed via SPM or the xcframework is
vendored directly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
cargo-swift drives the build through rustc, install_name_tool and
xcodebuild — none of which depend on the Swift compiler version. Pinning a
swiftly-managed Swift 6.0 toolchain added onboarding friction (and silently
broke when the registered toolchain went missing) without buying real
reproducibility, since Xcode/SDK selection is what actually shapes the
xcframework. Drop the SWIFT_VERSION env var and the swiftly wrapper and
invoke cargo-swift directly against the system toolchain.

Bump XROS_DEPLOYMENT_TARGET to 26.0 to match the visionOS 26 minimum
declared in Package@swift-6.2.swift.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Now that cargo-swift natively supports embedding the privacy manifest at
the package root and inside every .framework slice, drop the bespoke
swift-embed-privacy-manifest task and the post-generation cp into the
package root. The Makefile just passes --privacy-manifest pointing at
the existing support template and cargo-swift handles both placements.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
x86_64-apple-tvos is the Intel-flavored tvOS simulator and is permanently
tier-3 — there's no precompiled rust-std on any rustup channel, so
cargo-swift falls back to '-Z build-std', which doesn't build the
panic_abort runtime our release profile needs and fails to link with
E0463. Pass cargo-swift's new --exclude-arch flag to drop that arch from
the universal tvos-simulator slice; the slice collapses to arm64-only
(tvos-arm64-simulator), avoiding build-std entirely. Apple Silicon Mac
devs are unaffected; Intel Mac users lose tvOS simulator support, which
is an acceptable trade for everyone else getting working release builds.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@pblazej pblazej requested review from ladvoc and reenboog April 15, 2026 10:12
@pblazej
Copy link
Copy Markdown
Contributor Author

pblazej commented Apr 15, 2026

The only open question I've got so far is: dsyms yes/no

We'd need at least:

  [profile.release]
  debug = "limited"      # or = true (line tables + types). "limited" is enough for symbolication.
  strip = "none"         # currently "symbols" — strips DWARF along with everything else

Copy link
Copy Markdown
Contributor

@xianshijing-lk xianshijing-lk left a comment

Choose a reason for hiding this comment

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

lgtm

@pblazej pblazej merged commit 598d0e3 into main Apr 17, 2026
21 of 22 checks passed
@pblazej pblazej deleted the blaze/swift-uniffi-dylib branch April 17, 2026 13:06
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.

2 participants