Skip to main content
Version: Next

Screen Sharing for Expo React Native (iOS)

This guide walks you through integrating screen sharing functionality for iOS in your Expo React Native application using Video SDK.

Install the plugin:

npm install @videosdk.live/expo-ios-screen-share

Usage

Update your app.json to include the plugin along with your Apple Developer teamId and an optional extensionName:

{
"plugins": [
[
"@videosdk.live/expo-ios-screen-share",
{
"appleTeamId": "YOUR_APPLE_TEAM_ID", // example: "EHV7XZLAHA"
"extensionName": "YOUR_BROADCAST_EXTENSION_NAME",
}
],
]
}
info

If no extensionName is provided, the default value broadcast will be used.

What This Plugin Does

  • Adds a Broadcast Upload Extension target.
  • Configures App Group, Entitlements, and Info.plist entries.
  • Automatically links the broadcast extension with your main app target.
  • Minimizes manual native code configuration required for ReplayKit.
  • Provides a native bridge (VideosdkRPK.swift) for broadcasting control.

VideosdkRPK.js file

Create a JS bridge to interface with the native broadcast extension:

import { NativeModules, NativeEventEmitter, Platform } from 'react-native';

const { VideosdkRPK } = NativeModules;

if (!VideosdkRPK) {
console.warn('⚠️ Native Module VideosdkRPK is not loaded');
}

const emitter = Platform.OS === 'ios' && VideosdkRPK ? new NativeEventEmitter(VideosdkRPK) : null;

const VideosdkBridge = {
startBroadcast: Platform.OS === 'ios' ? () => VideosdkRPK?.startBroadcast() : () => {},
addListener: (callback) => {
if (!emitter) return { remove: () => {} };
return emitter.addListener('onScreenShare', callback);
},
removeListener: (subscription) => {
subscription?.remove?.();
},
};

export default VideosdkBridge;

Implementing Screen Share Controls

import VideosdkRPK from "./VideosdkRPK";

function ControlsContainer() {

const {toggleScreenShare} = useMeeting({});

useEffect(() => {
const subscription = VideosdkRPK.addListener((event) => {
if (event === "START_BROADCAST") {
toggleScreenShare();
} else if (event === "STOP_BROADCAST") {
toggleScreenShare();
}
});

return () => {
VideosdkRPK.removeListener(subscription);
};
}, []);

return (
<View
style={{
padding: 24,
flexDirection: "row",
justifyContent: "space-between",
}}
>
<Button
onPress={async () => {
VideosdkRPK.startBroadcast();
}}
buttonText={"Screen Share"}
backgroundColor={"#1178F8"}
/>
</View>
);
}

Got a Question? Ask us on discord