Skip to content

Commit a610eeb

Browse files
pblazejclaude
andauthored
Build xcframework (#973)
This is quite tricky/manual process, as tools like https://github.com/segment-integrations/swift-create-xcframework won't work with newer SPM (that does not allow direct `xcodeproj` generation, required for archiving) 💀 Install https://github.com/mxcl/swift-sh to handle dependencies. The ultimate test: - run `./scripts/xcframework.swift --local` - you should be able to replace the package with binaries for every platform <img width="468" height="167" alt="image" src="https://github.com/user-attachments/assets/7a08d09c-70a4-4676-8093-9b9769e3ba63" /> ### Repo This will land in https://github.com/livekit/client-sdk-swift-xcframework (with LICENSE, maybe copied README). ### Safety This is mostly additive, except `LK_XCFRAMEWORK` for internal imports. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 678c2da commit a610eeb

10 files changed

Lines changed: 571 additions & 2 deletions

File tree

AGENTS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ Key components:
6060

6161
Dependencies: LiveKitWebRTC, LiveKitUniFFI, SwiftProtobuf.
6262

63+
## Compile-Time Flags
64+
65+
- `LK_XCFRAMEWORK` — set in the generated xcodeproj by `scripts/xcframework.swift`; switches `import SwiftProtobuf` to `internal import` in proto files so it doesn't leak into `.swiftinterface`
66+
- `LK_BENCHMARK` — set when building benchmarks (`Benchmarks/`); skips `DeviceManager`/`AudioManager` init in `Room.init` to allow headless benchmark runs
67+
- `LK_SIGNPOSTS` — enables `os.signpost` instrumentation in `StateSync` for profiling lock contention in Instruments
68+
6369
## WebRTC
6470

6571
WebRTC handles the actual media transport (audio/video/data) between participants. The SDK abstracts WebRTC complexity behind `Room`, `Participant`, and `Track` APIs while LiveKit server coordinates signaling.

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ proto: protoc protoc-swift
55
${PROTO_SOURCE}/livekit_models.proto \
66
${PROTO_SOURCE}/livekit_rtc.proto \
77
${PROTO_SOURCE}/livekit_metrics.proto
8+
@# Use internal import for xcframework builds to keep SwiftProtobuf out of .swiftinterface
9+
@for f in Sources/LiveKit/protos/*.pb.swift; do \
10+
sed -i '' 's/^import SwiftProtobuf/#if LK_XCFRAMEWORK\ninternal import SwiftProtobuf\n#else\nimport SwiftProtobuf\n#endif/' "$$f"; \
11+
done
812

913
docs: swift-docs
1014
swift doc generate Sources/LiveKit \

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,20 @@ let package = Package(
5252
}
5353
```
5454

55-
### XCode
55+
### Xcode
5656

5757
Go to Project Settings -> Swift Packages.
5858

5959
Add a new package and enter: `https://github.com/livekit/client-sdk-swift`
6060

61+
### Pre-built XCFramework
62+
63+
A pre-built binary distribution is available for faster integration and CI builds. Add the XCFramework package instead:
64+
65+
`https://github.com/livekit/client-sdk-swift-xcframework`
66+
67+
This package bundles `LiveKit.xcframework` (dynamic framework) along with its dependencies (`LiveKitWebRTC`, `RustLiveKitUniFFI`). It contains the same code as the source package above, just pre-compiled.
68+
6169
### CocoaPods
6270

6371
> [!IMPORTANT]
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module LKObjCHelpers {
2+
header "include/LKObjCHelpers.h"
3+
export *
4+
}

Sources/LiveKit/Broadcast/LKSampleHandler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import Combine
2424
import OSLog
2525

2626
#if !COCOAPODS
27-
import LKObjCHelpers
27+
internal import LKObjCHelpers
2828
#endif
2929

3030
@available(macCatalyst 13.1, *)

Sources/LiveKit/Protos/livekit_metrics.pb.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
// For information on using the generated types, please see the documentation:
99
// https://github.com/apple/swift-protobuf/
1010

11+
#if LK_XCFRAMEWORK
12+
internal import SwiftProtobuf
13+
#else
1114
import SwiftProtobuf
15+
#endif
1216

1317
// If the compiler emits an error on this type, it is because this file
1418
// was generated by a version of the `protoc` Swift plug-in that is

Sources/LiveKit/Protos/livekit_models.pb.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ import FoundationEssentials
2727
#else
2828
import Foundation
2929
#endif
30+
#if LK_XCFRAMEWORK
31+
internal import SwiftProtobuf
32+
#else
3033
import SwiftProtobuf
34+
#endif
3135

3236
// If the compiler emits an error on this type, it is because this file
3337
// was generated by a version of the `protoc` Swift plug-in that is

Sources/LiveKit/Protos/livekit_rtc.pb.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@ import FoundationEssentials
2727
#else
2828
import Foundation
2929
#endif
30+
#if LK_XCFRAMEWORK
31+
internal import SwiftProtobuf
32+
#else
3033
import SwiftProtobuf
34+
#endif
3135

3236
// If the compiler emits an error on this type, it is because this file
3337
// was generated by a version of the `protoc` Swift plug-in that is

scripts/Package.swift.stencil

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// swift-tools-version:6.2
2+
// Auto-generated by scripts/xcframework.swift
3+
4+
import PackageDescription
5+
6+
let package = Package(
7+
name: "LiveKit",
8+
platforms: [
9+
.iOS(.v13),
10+
.macOS(.v10_15),
11+
.macCatalyst(.v14),
12+
.tvOS(.v17),
13+
.visionOS(.v26),
14+
],
15+
products: [
16+
.library(name: "LiveKit", targets: ["LiveKit", "LiveKitWebRTC", "RustLiveKitUniFFI"]),
17+
],
18+
targets: [{% if local %}
19+
.binaryTarget(name: "LiveKit", path: "LiveKit.xcframework.zip"),{% else %}
20+
.binaryTarget(
21+
name: "LiveKit",
22+
url: "{{ baseURL }}/LiveKit.xcframework.zip",
23+
checksum: "{{ checksumLiveKit }}"
24+
),{% endif %}
25+
.binaryTarget(
26+
name: "LiveKitWebRTC",
27+
url: "{{ webrtcURL }}",
28+
checksum: "{{ webrtcChecksum }}"
29+
),
30+
.binaryTarget(
31+
name: "RustLiveKitUniFFI",
32+
url: "{{ uniffiURL }}",
33+
checksum: "{{ uniffiChecksum }}"
34+
),
35+
]
36+
)

0 commit comments

Comments
 (0)