Skip to main content
The CometChat Calls SDK supports viewing screen shares from other participants. Screen sharing initiation on React Native requires platform-specific configuration.

View Screen Shares

When a participant shares their screen, the SDK automatically displays it. Listen for screen share events:
import { CometChatCalls } from '@cometchat/calls-sdk-react-native';

CometChatCalls.addEventListener('onParticipantStartedScreenShare', (participant) => {
  console.log(`${participant.name} started screen sharing`);
});

CometChatCalls.addEventListener('onParticipantStoppedScreenShare', (participant) => {
  console.log(`${participant.name} stopped screen sharing`);
});

Start Screen Sharing

Start sharing your screen:
CometChatCalls.startScreenSharing();

Stop Screen Sharing

Stop sharing your screen:
CometChatCalls.stopScreenSharing();

Screen Share Events

Local Screen Share

CometChatCalls.addEventListener('onScreenShareStarted', () => {
  console.log('Screen sharing started');
});

CometChatCalls.addEventListener('onScreenShareStopped', () => {
  console.log('Screen sharing stopped');
});

Button Click Event

CometChatCalls.addEventListener('onScreenShareButtonClicked', () => {
  console.log('Screen share button clicked');
});

iOS Configuration

Enable Broadcast Upload Extension

To enable screen sharing on iOS, you need to add a Broadcast Upload Extension:
  1. In Xcode, go to File > New > Target
  2. Select Broadcast Upload Extension
  3. Name it (e.g., ScreenShareExtension)
  4. Set the same Team and Bundle Identifier prefix as your main app

Configure App Groups

  1. Select your main app target
  2. Go to Signing & Capabilities
  3. Add App Groups capability
  4. Create a new group (e.g., group.com.yourcompany.yourapp)
  5. Repeat for the Broadcast Upload Extension target

Update Info.plist

Add to your extension’s Info.plist:
<key>NSExtension</key>
<dict>
    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.broadcast-services-upload</string>
    <key>NSExtensionPrincipalClass</key>
    <string>SampleHandler</string>
    <key>RPBroadcastProcessMode</key>
    <string>RPBroadcastProcessModeSampleBuffer</string>
</dict>

Android Configuration

Add Permissions

Add to your AndroidManifest.xml:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />

Configure Foreground Service

For Android 10+, screen sharing requires a foreground service. Add to your AndroidManifest.xml:
<service
    android:name="com.cometchat.calls.ScreenCaptureService"
    android:foregroundServiceType="mediaProjection"
    android:exported="false" />

Pin Screen Share

Pin a participant’s screen share to the main view:
CometChatCalls.pinParticipant(participantId, 'screen-share');

Layout Behavior

When screen sharing starts:
  • The SDK automatically switches to Sidebar layout
  • The screen share is displayed in the main view
  • Other participants appear in the sidebar
When screen sharing stops:
  • The layout returns to the previous state (if it was programmatically set)

Complete Example

import React, { useState, useEffect } from 'react';
import { View, TouchableOpacity, Text, StyleSheet, Alert } from 'react-native';
import { CometChatCalls } from '@cometchat/calls-sdk-react-native';

function ScreenShareControls() {
  const [isSharing, setIsSharing] = useState(false);
  const [remoteSharer, setRemoteSharer] = useState<string | null>(null);

  useEffect(() => {
    const unsubscribeStart = CometChatCalls.addEventListener(
      'onScreenShareStarted',
      () => {
        setIsSharing(true);
      }
    );

    const unsubscribeStop = CometChatCalls.addEventListener(
      'onScreenShareStopped',
      () => {
        setIsSharing(false);
      }
    );

    const unsubscribeRemoteStart = CometChatCalls.addEventListener(
      'onParticipantStartedScreenShare',
      (participant) => {
        setRemoteSharer(participant.name);
      }
    );

    const unsubscribeRemoteStop = CometChatCalls.addEventListener(
      'onParticipantStoppedScreenShare',
      () => {
        setRemoteSharer(null);
      }
    );

    return () => {
      unsubscribeStart();
      unsubscribeStop();
      unsubscribeRemoteStart();
      unsubscribeRemoteStop();
    };
  }, []);

  const toggleScreenShare = () => {
    if (isSharing) {
      CometChatCalls.stopScreenSharing();
    } else {
      if (remoteSharer) {
        Alert.alert(
          'Screen Share Active',
          `${remoteSharer} is currently sharing their screen.`
        );
        return;
      }
      CometChatCalls.startScreenSharing();
    }
  };

  return (
    <View style={styles.container}>
      {remoteSharer && (
        <Text style={styles.sharingText}>
          {remoteSharer} is sharing their screen
        </Text>
      )}
      <TouchableOpacity
        style={[styles.button, isSharing && styles.activeButton]}
        onPress={toggleScreenShare}
      >
        <Text style={styles.buttonText}>
          {isSharing ? 'Stop Sharing' : 'Share Screen'}
        </Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    padding: 16,
    alignItems: 'center',
  },
  sharingText: {
    color: '#6851D6',
    fontSize: 14,
    marginBottom: 8,
  },
  button: {
    backgroundColor: '#333',
    paddingHorizontal: 20,
    paddingVertical: 12,
    borderRadius: 8,
  },
  activeButton: {
    backgroundColor: '#6851D6',
  },
  buttonText: {
    color: '#fff',
    fontSize: 14,
    fontWeight: '600',
  },
});

export default ScreenShareControls;