Skip to main content
LiveKit integrates with platform-specific APIs to support screen sharing on both iOS and macOS.

Quick Start

Enable screen sharing with a single method call:
try await room.localParticipant.setScreenShare(enabled: true)
On iOS, LiveKit supports two screen capture modes:
  • In-app Capture (default): Share screen content within your app only
  • Broadcast Capture: Share screen content even when users switch to other apps

iOS Screen Sharing

In-App Capture

By default, LiveKit uses In-app Capture mode, which requires no additional configuration. When screen sharing is enabled, the system prompts the user with a screen recording permission dialog.
// Enable in-app screen sharing
try await room.localParticipant.setScreenShare(enabled: true)
Limitations:
  • Only captures content within your app
  • Application audio is not supported
  • Permission prompt appears once per app execution

Broadcast Capture

Broadcast Capture mode allows capturing screen content system-wide, including when the app is in the background. This requires setting up a Broadcast Upload Extension.
1
Add Broadcast Upload Extension Target
2
  • In Xcode, choose File > New > Target
  • Select Broadcast Upload Extension from the template chooser
  • Name the extension (e.g., “BroadcastExtension”)
  • Click Finish
  • In the Signing & Capabilities tab, set the bundle identifier to <main-app-bundle-id>.broadcast
  • Replace the default content of SampleHandler.swift with:
  • 3
    import LiveKit
    
    #if os(iOS)
    @available(macCatalyst 13.1, *)
    class SampleHandler: LKSampleHandler {
        override var enableLogging: Bool { true }
    }
    #endif
    
    4
    Overriding enableLogging to true enables logging in the extension’s process, making logs available through the macOS Console app for troubleshooting.
    5
    Add Targets to Common App Group
    6
    Both your app and the broadcast extension must be members of the same app group.
    7
    For both the main app target and broadcast extension target:
    8
  • Select the target in the Project Editor
  • Go to the Signing & Capabilities tab
  • Click + Capability and add App Groups
  • Click + to add a new app group
  • Add the target to the group group.<main-app-bundle-id>
  • 9
    Enable Screen Share
    10
    With the broadcast extension configured, broadcast capture is used automatically:
    11
    try await room.localParticipant.setScreenShare(enabled: true)
    
    12
    When using broadcast capture, capture options must be set as room defaults rather than passed directly to setScreenShare().

    Application Audio

    When using Broadcast Capture, you can capture app audio even when users navigate away from your app. The captured audio is mixed with the microphone track:
    let roomOptions = RoomOptions(
        defaultScreenShareCaptureOptions: ScreenShareCaptureOptions(
            appAudio: true  // Enable app audio capture
        )
    )
    
    try await room.connect(
        url: wsURL,
        token: token,
        roomOptions: roomOptions
    )
    
    try await room.localParticipant.setMicrophone(enabled: true)
    try await room.localParticipant.setScreenShare(enabled: true)
    

    Troubleshooting iOS Screen Sharing

    To debug broadcast extension issues:
    1. Launch the Console app on macOS
    2. Select your iOS device from the left sidebar
    3. Click Start Streaming
    4. In the search bar, filter for messages with category “LKSampleHandler”
    5. Initiate a screen share in your app and inspect Console for errors

    Advanced: Manual Track Publication

    By default, when a broadcast begins externally (e.g., via Control Center), the local participant automatically publishes a screen share track. To handle publication manually:
    // Disable automatic publication
    BroadcastManager.shared.shouldPublishTrack = false
    
    // Monitor broadcast state changes
    let subscription = BroadcastManager.shared
        .isBroadcastingPublisher
        .sink { isBroadcasting in
            if isBroadcasting {
                // Manually publish screen share track
                Task {
                    try? await room.localParticipant.setScreenShare(enabled: true)
                }
            }
        }
    
    Or use a delegate:
    class MyDelegate: BroadcastManagerDelegate {
        func broadcastManager(didChangeState isBroadcasting: Bool) {
            // Handle broadcast state change
        }
    }
    
    BroadcastManager.shared.delegate = MyDelegate()
    

    Custom Identifiers

    By default:
    • App group identifier: group.<main-app-bundle-id>
    • Broadcast extension bundle ID: <main-app-bundle-id>.broadcast
    To override these:
    1. Set RTCAppGroupIdentifier in Info.plist for both targets
    2. Set RTCScreenSharingExtension in Info.plist for the main app

    macOS Screen Sharing

    On macOS, LiveKit captures the main screen by default:
    try await room.localParticipant.setScreenShare(enabled: true)
    

    Advanced: Capture Specific Display or Window

    For more control over what to capture:
    if #available(macOS 12.3, *) {
        // Get the main display
        let mainDisplay = try await MacOSScreenCapturer.mainDisplaySource()
        
        // Create screen share track
        let screenTrack = LocalVideoTrack.createMacOSScreenShareTrack(
            source: mainDisplay,
            options: ScreenShareCaptureOptions(
                dimensions: .h1080_169,
                fps: 15,
                showCursor: true
            )
        )
        
        // Publish the track
        try await room.localParticipant.publish(videoTrack: screenTrack)
    }
    

    Screen Share Capture Options

    Configure screen sharing with ScreenShareCaptureOptions:
    let options = ScreenShareCaptureOptions(
        dimensions: .h1080_169,      // Resolution
        fps: 15,                     // Frame rate
        showCursor: true,            // Show cursor (macOS only)
        appAudio: false              // Capture app audio (iOS broadcast only)
    )
    
    let roomOptions = RoomOptions(
        defaultScreenShareCaptureOptions: options
    )
    

    Disable Screen Sharing

    To stop screen sharing:
    try await room.localParticipant.setScreenShare(enabled: false)
    

    See Also

    • LocalParticipant.swift:355 (setScreenShare(enabled:))
    • Docs/ios-screen-sharing.md

    Build docs developers (and LLMs) love