A simple few steps to integrate our React Native SDK and enjoy the seamless meetings in your app.
Install @dell-emc/react-native-meeting-sdk with npm
1. Run => npm i @dell-emc/react-native-meeting-sdk
2. Dependency conflicts may occur between RNSDK and your app.
If that is the case, please run npm i @dell-emc/react-native-meeting-sdk --force.
3. add this script to your package.json scripts =>
"update-deps": "node node_modules/@dell-emc/react-native-meeting-sdk/update_dependencies.js"
4.To check if some dependencies need to be added, please run the following script
=> npm run update-deps.
This will sync all of our peer dependencies with your dependencies.
Next you will need to do npm install.
*In index.ts or index.js
Add this line import "react-native-get-random-values"
- In
android/app/src/debug/AndroidManifest.xml
andandroid/app/src/main/AndroidManifest.xml
, please include:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CAMERA" android:minSdkVersion="34"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" android:minSdkVersion="34" />
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BIND_TELECOM_CONNECTION_SERVICE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application>
// ...
<activity>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
<data android:mimeType="video/*" />
<data android:mimeType="audio/*" />
<data android:mimeType="application/*" />
<data android:mimeType="text/plain" />
<!-- Add the mime types you want to support -->
</intent-filter>
</activity>
// ...
<service android:name="io.wazo.callkeep.VoiceConnectionService" android:exported="true" android:label="Wazo" android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE" android:foregroundServiceType="camera|microphone">
<intent-filter>
<action android:name="android.telecom.ConnectionService" />
</intent-filter>
</service>
<meta-data android:name="com.google.android.geo.API_KEY" android:value="Your_Google_Api_Key"/>
<service android:name="io.wazo.callkeep.RNCallKeepBackgroundMessagingService" />
// ....
</application>
- For icons to work, you should add these lines to
app/build.gradle
project.ext.vectoricons = [
iconFontNames: [ 'MaterialIcons.ttf', 'EvilIcons.ttf', 'AntDesign.ttf', 'Entypo.ttf', 'Feather.ttf', 'FontAwesome.ttf', 'FontAwesome5_Brands.ttf', 'FontAwesome5_Regular.ttf', 'FontAwesome5_Solid.ttf', 'Foundation.ttf', 'Ionicons.ttf', 'MaterialCommunityIcons.ttf', 'SimpleLineIcons.ttf', 'Octicons.ttf', 'Zocial.ttf' ]
]
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
- For GIF to work, you should add these lines to
app/build.gradle
under dependencies
// For animated gif support
implementation 'com.facebook.fresco:animated-gif:3.1.3'
// For webp support
implementation 'com.facebook.fresco:animated-webp:3.1.3'
// Animated webp support
implementation 'com.facebook.fresco:webpsupport:3.1.3'
- Add these lines to your
AppDelegate.mm
file
#import "RNCallKeep.h"
#import <WebRTC/RTCAudioSession.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
....
RTCAudioSession *session = [RTCAudioSession sharedInstance];
session.useManualAudio = true;
session.isAudioEnabled = false;
....
}
- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void(^)(NSArray<id<UIUserActivityRestoring>> * __nullable restorableObjects))restorationHandler
{
return [RNCallKeep application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
- SDK requests some permissions, make sure to include the required entries in your Info.plist file.
<key>NSCameraUsageDescription</key>
<string>The App would like access your camera to make video calls in chats or to takes photos for the profile, chat, and group pictures.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>The App would like access your location in order to share your current location in chats.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>The App would like access your location in order to share your current location in chats.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>The App would like access your location in order to share your current location in chats.</string>
<key>NSMicrophoneUsageDescription</key>
<string>The App would like access your microphone to make and receive calls and record voice messages in chats.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>The App would like access your gallery to upload and download pictures in chats or for profile and group pictures.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>The App would like access your gallery to upload and download pictures in chats or for profile and group pictures.</string>
-
Allow voip background on IOS.
Open
Info.plist
file and add voip inUIBackgroundModes
.
<key>UIBackgroundModes</key>
<array>
<string>voip</string>
</array>
- For IOS, for icons to work. Edit
Info.plist
and add a property calledFonts
provided by application
List of all available fonts to copy & paste in Info.plist
<key>UIAppFonts</key>
<array>
<string>AntDesign.ttf</string>
<string>Entypo.ttf</string>
<string>EvilIcons.ttf</string>
<string>Feather.ttf</string>
<string>FontAwesome.ttf</string>
<string>FontAwesome5_Brands.ttf</string>
<string>FontAwesome5_Regular.ttf</string>
<string>FontAwesome5_Solid.ttf</string>
<string>FontAwesome6_Brands.ttf</string>
<string>FontAwesome6_Regular.ttf</string>
<string>FontAwesome6_Solid.ttf</string>
<string>Foundation.ttf</string>
<string>Ionicons.ttf</string>
<string>MaterialIcons.ttf</string>
<string>MaterialCommunityIcons.ttf</string>
<string>SimpleLineIcons.ttf</string>
<string>Octicons.ttf</string>
<string>Zocial.ttf</string>
<string>Fontisto.ttf</string>
</array>
- React Native uses event-target-shim@5 which is not compatible with react-native-webrtc's dependency on event-target-shim@6. To fix this, you may need to add a redirection in your
metro.config.js
file:
// metro.config.js
// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require("expo/metro-config");
const resolveFrom = require("resolve-from");
/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);
config.resolver.resolveRequest = (context, moduleName, platform) => {
if (
// If the bundle is resolving "event-target-shim" from a module that is part of "react-native-webrtc".
moduleName.startsWith("event-target-shim") &&
context.originModulePath.includes("react-native-webrtc")
) {
// Resolve event-target-shim relative to the react-native-webrtc package to use v6.
// React Native requires v5 which is not compatible with react-native-webrtc.
const eventTargetShimPath = resolveFrom(
context.originModulePath,
moduleName
);
return {
filePath: eventTargetShimPath,
type: "sourceFile",
};
}
// Ensure you call the default resolver.
return context.resolveRequest(context, moduleName, platform);
};
module.exports = config;
Events supported :
Prop | Description |
---|---|
onConferenceWillJoin |
If the meeting is loading and its trying to connect |
onAudioMutedChanged |
When mic mute status changes |
onVideoMutedChanged |
When video status changes |
onConferenceJoined |
When the user joins |
onParticipantJoined |
When a meeting participant joins |
onConferenceLeft |
When the user leaves the meeting |
onParticipantLeft |
When a meeting participant leaves |
onReadyToClose |
When hangup the meeting |
const onReadyToClose = () => {
console.log("Room Closed");
}
const eventListeners = {
onReadyToClose : onReadyToClose
};
return(
<MeetingSDK
...
eventListeners={eventListeners}
...
Prop | Description | Default |
---|---|---|
themeMode |
Change between light and dark modes | dark |
theme |
Set of custom props to customize the coloring o the app | preset of colors defined internally |
Allowed theme props are:
Note: you can provide all colors or only a few of them.
Prop | Description |
---|---|
primaryColor |
Main color of the screens |
secondaryColor |
For buttons, icons (not icon buttons) |
accentColor |
For bottom sheets |
primaryTextColor |
Main text color used in most of the app |
secondaryTextColor |
For buttons text, icon buttons text, secondary text |
<MeetingSDK
...
themeMode={"light"} // "light", "dark"
theme={{ // default colors will be used if theme is not provided
dark:{
primaryColor:"#232323",
secondaryColor: "#b5986b",
accentColor:"#141414",
primaryTextColor: "#ffffff",
secondaryTextColor: "#ffffff",
},
light:{
primaryColor:"#eeeeee",
secondaryColor: "#b5986b",
accentColor:"#d1d1d1",
primaryTextColor: "#000000",
secondaryTextColor: "#ffffff",
}
}}
/>
The dynamicActions feature in the MeetingSDK allows users to define and include custom actions within the meeting environment. These actions can be triggered by users during the meeting session, providing additional functionality and interactivity.
The dynamicActions property is passed to the MeetingSDK component as an array of action objects. Each action object contains the following properties:
-
text
: A string representing the label or text associated with the action. -
iconProps
: An object specifying the properties of the icon to be displayed alongside the action text. This object includes:-
type
: The type of icon library to be used ('fontisto' | 'material' | 'evil' | 'feather' | 'ant' | 'simpleLine' | 'zocial' | 'foundation' | 'fa5' | 'fa' | 'ionicon' | 'materialCommunity' | 'entypo' | 'octicon'). -
name
: The name or identifier of the icon within the specified icon library (checkreact-native-vector-icons
). -
color
(optional): The color of the icon.
-
-
onClick
: A function that defines the behavior to be executed when the action is triggered. This function should handle the desired functionality or interaction associated with the action. .
...
const handleAction=(externalMeetingRef : string)=>{
````your action functionality ````
const meetingRefId = externalMeetingRef
}
const dynamicActions : IDynamicActions [] = [
{
text :"Test dynamic action",
iconProps :{type :'material' , name :'sos' , color :'white'},
onClick : handleAction
}
]
return(
<MeetingSDK
...
dynamicActions={dynamicActions}
...
This configuration object will allow users to manage file upload limitations, and blocked file formats
Prop | Type | Description | Default |
---|---|---|---|
maxFileUploadSize |
number |
Maximum allowed size for file uploads, in Byte. | 104857600 |
fileUploadFormat |
string[] |
Allowed file formats for uploads. | ['audio', 'application','text','video','image'] |
blockedFileFormatMimeType |
string[] |
List of MIME types to block for file uploads. | ['application/exe','application/zip'] |
<MeetingSDK
...
messagesConfig={{
maxFileUploadSize: 104857600, // Maximum file upload size (in byte).
fileUploadFormat: [// Allowed file formats for uploading.
"audio",
"application",
"text",
"video",
"image"
],
blockedFileFormatMimeType: [// List of blocked MIME types for file uploads.
"application/x-octet-stream",
"application/x-msdownload",
"application/exe",
"application/dos-",
"vms/exe",
"application/x-winexe",
"application/msdos-window",
"application/x-msdos-program",
"application/x-winzip",
"application/x-zip",
"application/x-zip-compressed",
"application/zip"
]
}}
/>
Function | Return Type |
---|---|
endMeeting() | void |
triggers the necessary functionality to gracefully end your meeting, handling tasks such as disconnecting from the meeting, cleaning up resources, and notifying other participants.
When you're ready to end your meeting, Import endMeeting in your code then simply call endMeeting()
import { endMeeting } from "@dell-emc/react-native-meeting-sdk";
endMeeting();
-
react-native-reanimated failed to create a worklet :https://docs.swmansion.com/react-native-reanimated/docs/guides/troubleshooting/#failed-to-create-a-worklet
-
For socket connection, you may need to pass
socketPath
. check the link https://socket.io/docs/v4/client-options/#path -
You might face an issue related to setup-permission from react-native-permissions. refer to this link please https://github.com/zoontek/react-native-permissions?tab=readme-ov-file#ios
import {MeetingSDK , endMeeting} from '@dell-emc/react-native-meeting-sdk';
function App() {
const accountId = "ACCOUNT ID";
const serverURL = "SERVER URL";
const jwtToken = "MEETING TOKEN";
const authCode = "AUTH CODE RECENTLY GENERATED"
const meetingId = "EXTERNAL MEETING REF"
const socketDomain = "https://example.com";
const placesApiKey = "GOOGLE_PLACES_API_KEY"
/* Optional: socket path is the name of the path that is captured on the server side.*/
const socketPath = "/my-custom-path/socket.io/"
const onReadyToClose= () => {
console.log("Room Closed");
}
const eventListeners = {
onReadyToClose :onReadyToClose
};
const handleAction=()=>{
console.log("handle dynamic action click")
}
const dynamicActions : IDynamicActions [] = [
{
text :"Test dynamic action",
iconProps :{type :'material' , name :'sos' , color :'white'},
onClick : handleAction
}
]
const endMeeting = () => {
endMeeting()
}
return (
<MeetingSDK
appName={appName}
serverURL={serverURL}
socketURL={socketURL}
accountId={accountId}
jwtToken={jwtToken}
authCode={authCode}
meetingId={meetingId} // Required when using authCode
/* please create your own gifApiKey for your app ( https://developers.giphy.com/dashboard/ )
if you don't send gifApiKey, gif on chat will be disabled */
gifApiKey={gifApiKey}
eventListeners={eventListeners}
dynamicActions={dynamicActions}
locale={"en"} // "en", "ar"
themeMode={"light"} // "light", "dark"
theme={{ // default colors will be used if theme is not provided
dark:{
primaryColor:"#232323",
secondaryColor: "#b5986b",
accentColor:"#141414",
primaryTextColor: "#ffffff",
secondaryTextColor: "#ffffff",
},
light:{
primaryColor:"#eeeeee",
secondaryColor: "#b5986b",
accentColor:"#d1d1d1",
primaryTextColor: "#000000",
secondaryTextColor: "#ffffff",
}
}}
placesApiKey={placesApiKey}
messagesConfig={{
maxFileUploadSize: 104857600, // Maximum file upload size (in byte).
fileUploadFormat: [// Allowed file formats for uploading.
"audio",
"application",
"text",
"video",
"image"
],
blockedFileFormatMimeType: [// List of blocked MIME types for file uploads.
"application/x-octet-stream",
"application/x-msdownload",
"application/exe",
"application/dos-",
"vms/exe",
"application/x-winexe",
"application/msdos-window",
"application/x-msdos-program",
"application/x-winzip",
"application/x-zip",
"application/x-zip-compressed",
"application/zip"
]
}}
/>
);
}