Describe the bug
Since 2.4.0, setScreenShareEnabled(true) on iOS unconditionally routes into the Broadcast Upload Extension flow. ScreenShareCaptureOptions.useiOSBroadcastExtension still exists, but false (the documented in-app RPScreenRecorder mode through 2.3.6) has no effect.
lib/src/participant/local.dart (2.4.0–2.10.0 and current main):
if (lkPlatformIs(PlatformType.iOS) && !BroadcastManager().isBroadcasting) {
// Wait until broadcasting to publish track
await BroadcastManager().requestActivation();
return null;
}
The branch precedes any capture options inspection; the in-app path below it is unreachable.
Worse, without an extension: requestActivation()'s native side (ios/Classes/BroadcastManager.swift) guard-returns when the RTCScreenSharingExtension Info.plist key is absent:
func requestActivation() {
guard let bundleIdentifier = BroadcastBundleInfo.screenSharingExtension else { return }
Task { await Self.showPicker(for: bundleIdentifier) }
}
No picker, no consent UI, no error, and no log so the call resolves null as success.
This appears to be an unintended side effect of #705 ("fix: Properly handle broadcast capture state"): the PR documents its async-return breaking change but never mentions useiOSBroadcastExtension or the in-app path. That capturer still works in flutter_webrtc, reachable via LocalVideoTrack.createScreenShareTrack() + publishVideoTrack() which is our current workaround.
Broadcast extension capture is always whole screen; in-app capture is scoped to the app's own UI. For privacy sensitive products (share this app with a support agent, never the user's other apps or notifications), app scoped capture is impossible through the public screenshare API on every released version.
To Reproduce
- Flutter app on a physical iPhone,
livekit_client ≥ 2.4.0, no Broadcast Upload Extension target.
- Connect to a room, then:
await room.localParticipant!.setScreenShareEnabled(
true,
screenShareCaptureOptions:
const ScreenShareCaptureOptions(useiOSBroadcastExtension: false),
);
- The call resolves (
null); no consent UI, no published track, nothing logged. Remote participants receive nothing.
- On 2.3.6 the same code shows the ReplayKit consent alert and publishes an in-app screenshare track.
Expected behavior
useiOSBroadcastExtension: false (explicit or via RoomOptions.defaultScreenShareCaptureOptions) uses the in-app capturer, as through 2.3.6 . The gate should consult the effective capture options before routing to BroadcastManager.
- Independently: when the broadcast flow is requested but
RTCScreenSharingExtension is missing, fail loudly (throw or error event) instead of a silent null. Currently misconfiguration looks like success.
Platform information
- Flutter version: 3.44.2
- Plugin version: reproduced on 2.7.0 and 2.10.0 ; unchanged on
main, 2026-08-04
- Flutter target OS: iOS (real device, iPhone 17)
- Flutter target OS version: iOS 26.4
- Flutter console log: n/a, failure produces no output
Describe the bug
Since 2.4.0,
setScreenShareEnabled(true)on iOS unconditionally routes into the Broadcast Upload Extension flow.ScreenShareCaptureOptions.useiOSBroadcastExtensionstill exists, butfalse(the documented in-appRPScreenRecordermode through 2.3.6) has no effect.lib/src/participant/local.dart(2.4.0–2.10.0 and currentmain):The branch precedes any capture options inspection; the in-app path below it is unreachable.
Worse, without an extension:
requestActivation()'s native side (ios/Classes/BroadcastManager.swift) guard-returns when theRTCScreenSharingExtensionInfo.plist key is absent:No picker, no consent UI, no error, and no log so the call resolves
nullas success.This appears to be an unintended side effect of #705 ("fix: Properly handle broadcast capture state"): the PR documents its async-return breaking change but never mentions
useiOSBroadcastExtensionor the in-app path. That capturer still works influtter_webrtc, reachable viaLocalVideoTrack.createScreenShareTrack()+publishVideoTrack()which is our current workaround.Broadcast extension capture is always whole screen; in-app capture is scoped to the app's own UI. For privacy sensitive products (share this app with a support agent, never the user's other apps or notifications), app scoped capture is impossible through the public screenshare API on every released version.
To Reproduce
livekit_client≥ 2.4.0, no Broadcast Upload Extension target.null); no consent UI, no published track, nothing logged. Remote participants receive nothing.Expected behavior
useiOSBroadcastExtension: false(explicit or viaRoomOptions.defaultScreenShareCaptureOptions) uses the in-app capturer, as through 2.3.6 . The gate should consult the effective capture options before routing toBroadcastManager.RTCScreenSharingExtensionis missing, fail loudly (throw or error event) instead of a silentnull. Currently misconfiguration looks like success.Platform information
main, 2026-08-04