SIGN UP
Navigation

Using React Native SDK

This guide provides you with the basics of using the Voximplant React Native SDK of version > 1.0.0. (see the Migration guide in case of using Legacy API). Step-by-step, you’ll create the simplest application to make and receive audio/video calls. You can start by downloading our demo application.

You can make and receive calls using your device’s data connection to/from any other endpoint that works with Voximplant: other mobile app built using either the iOS or Android SDKs, a web application built using the Web SDK, SIP phones and phone numbers all over the world.

IN CASE IF YOU DON'T KNOW VOXIMPLANT BASICS
A cloud scenario is required to make our cloud handle calls; the Applications allow linking scenarios, phone numbers, users, and call queues. Feel a bit confused?
Check our quickstart on scenarios, users, and applications: https://voximplant.com/docs/references/articles/quickstart 

Add Voximplant React Native SDK to the project

iOS

Manual install

  1. Make sure you have a React Native project created with react-native init ProjectName
  2. cd into a project directory where the package.json file is located.
  3. Run npm install react-native-voximplant@latest --save
  4. Open or create ios/Podfile and add the following dependencies:
    pod 'React', :path => ‘../node_modules/react-native', :subspecs => [
        'Core',
        'RCTImage',
        'RCTNetwork',
        'RCTText',
        'RCTWebSocket',
        'DevSupport',
        'BatchedBridge'
        # Add any other subspecs you want to use in your project
    ]
    pod 'react-native-voximplant', path: '../node_modules/react-native-voximplant'
    pod 'Yoga', path: '../node_modules/react-native/ReactCommon/yoga'
    Please take a look at the demo project Podfile as an example.
  5. Add use_frameworks! at the top of your target configuration
  6. Run pod install from <your_project>/ios/
  7. Start XCode and open generated <your_project>.xcworkspace
  8. Check if there is no *.xcodeproj in the project navigation (see the Libraries section). In case of any, please remove them. Since React dependencies are added via Podfile, double integration of its modules may lead to unpredictable/incorrect behavior of an application.
  9. Run your project (Cmd+R)

Android

Manual install

  1. Make sure you have "React Native" project created with react-native init
  2. cd into a project directory where the package.json file is located.
  3. Run npm install react-native-voximplant@latest --save
  4. It is required to add Java 8 support. 
    1. Open the android/app/build.gradle file and add the following lines to the ‘android’ section: 
      compileOptions {
          sourceCompatibility JavaVersion.VERSION_1_8
          targetCompatibility JavaVersion.VERSION_1_8
      }
    2. If you're using gradle version < 3.0.0, do this step and the next one OR run the gradle sync command in Android Studio, then follow the provided hints.
      Open the android/build.gradle file and update the Android plugin for gradle: 
      dependencies {
          // use the latest available version
          classpath 'com.android.tools.build:gradle:3.1.3'
      }
    3. Open the android/gradle/wrapper/gradle-wrapper.properties file and edit the distributionUrl to gradle-4.4-all.zip: 
      distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
  5. Run the react-native link command to link react-native-voximplant Android dependency OR perform the following steps:  
    1. Open up android/app/main/java/[...]/MainApplication.java.
    2. Add import com.voximplant.reactnative.VoxImplantReactPackage; to the imports at the top of the file.
      Add new VoxImplantReactPackage() to the list returned by the getPackages method
    3. Append the following lines to android/settings.gradle
      include ':react-native-voximplant'
      project(':react-native-voximplant').projectDir = new File(
          rootProject.projectDir,
          '../node_modules/react-native-voximplant/android'
      )
    4.  Insert the following lines inside the dependencies block in android/app/build.gradle
      compile project(':react-native-voximplant')

Initialization

To use React Native SDK, firstly make an import from the react-native-voximplant:

import {Voximplant} from 'react-native-voximplant';

Voximplant.Client is a singleton and the main class of the SDK that provides access to Voximplant’s functions, Voximplant.getInstance method is used to get its instance:

const client = Voximplant.getInstance();

You can pass Voximplant.ClientConfig while initialization, like this:

let clientConfig = {};
clientConfig.enableVideo = true; // Android only option
clientConfig.saveLogsToFile = true; // iOS only option
let client = Voximplant.getInstance(clientConfig);

The Voximplant.ClientConfig object can be passed to the Voximplant.getInstance method as an optional parameter. It lets you specify SDK settings; note that these settings are platform dependent, i.e., some parameters work only for iOS, others – for Android.

Connect and Login

Note that React Native SDK supports promises, i.e., you can handle any type of login independently since promises provide you an async/await construction. For example, if login with a password is handled with its own handler, whereas login with a token could be handled in another way. But still, events are supported too.

The Voximplant.Client.getClientState method is used to get the current state of connection to the Voximplant cloud and perform the actions according to it.

async function login() {
    try {
        let state = await client.getClientState();
        if (state === Voximplant.ClientState.DISCONNECTED) {
            await client.connect();
        } 
        let authResult = await client.login("userName", "password");
    } catch (e) {
        console.log(e.name + e.message);
    }
}

Make calls

To initiate a call we need the Voximplant.Client.call method. There is a Voximplant.CallSettings structure which could contain custom data, video directions and extra headers (SIP headers).

Since the call can behave in different ways, there is a group of call events – Voximplant.CallEvents. They can be triggered by the Voximplant.Call class instance as the class contains all the functionality for call management.

NOTIFICATION

There is a difference between resolving the Voximplant.Client.call promise and handling Voximplant.CallEvents. 
If the promise is resolved, the SDK sends a call to the cloud. However, it doesn't mean that a call is connected; to catch this call state, subscribe to the Voximplant.CallEvents.Connected event.
If the promise is rejected, that indicates the issues in the application's code (e.g., a try to make a call without login to the Voximplant cloud); in case of the CallFailed event is triggered, that means a telecom-related issue (e.g., another participant rejects a call).

 
async function makeCall() {
    const callSettings = {
        video: {
            sendVideo: true,
            receiveVideo: true,
        }
    };
    // create and start a call
    let call = await client.call("number", callSettings); 
    call.on(Voximplant.CallEvents.Connected, _onCallConnected);
}
function _onCallConnected(event) {
    // 'event' here is the instance of
    // the Voximplant.CallEvents.Connected object;
    // use event.call to get the instance of Voximplant.Call
}

Receiving calls

The IncomingCall event is a part of Voximplant.ClientEvents; handlers can be assigned via the Voximplant.Client.on API. You can get a Voximplant.Call instance from the Voximplant.ClientEvents.IncomingCall event.

There are three methods for an incoming call: answer, decline and reject. An audio/video stream can be sent only after the answer method call.

client.on(Voximplant.ClientEvents.IncomingCall, _incomingCall);
function _incomingCall(event) {
    const callSettings = {
        video: {
            sendVideo: event.video,
            receiveVideo: event.video
        }
    };
    event.call.answer(callSettings);
}

Endpoints

The Voximplant.Endpoint class represents any remote media unit in a call (Web/iOS/Android application, SIP or regular phone, etc.). Each Endpoint instance has built-in methods for managing video streams and also contains:

  • displayName, which is specified while creating a user in the Voximplant control panel
  • sipUri of an Endpoint
  • userName in terms of sipUri

Endpoints have their own events, e.g., to detect starting or terminating of receiving a video stream from a remote participant.

Note that the Voximplant.Call instance has the Voximplant.Call.getEndpoints method to retrieve all current endpoints for a call; it also has the Voximplant.CallEvents.EndpointAdded event on adding a new endpoint. We recommend assigning handlers for the Voximplant.EndpointEvents at the moment when the Voximplant.CallEvents.EndpointAdded event is triggered.

call.on(Voximplant.CallEvents.EndpointAdded, _onCallEndpointAdded);
function _onCallEndpointAdded(event) {
    console.log('_onCallEndpointAdded');
}

Video streams and video views

The rendering is managed via the Voximplant.VideoStream class and Voximplant.VideoView component.

The VideoStream class contains a unique id for a video stream; that id is passed into the VideoView component via props.

The VideoView component renders a video stream with its id and scaleType (possible values are SCALE_FIT, SCALE_FILL). Each video stream should be rendered via the separate VideoView component instance:

<Voximplant.VideoView 
         style={styles.selfview} 
         videoStreamId={this.state.localVideoStreamId} 
         scaleType={Voximplant.RenderScaleType.SCALE_FIT}/>
<Voximplant.VideoView 
        style={styles.remotevideo} 
        videoStreamId={this.state.remoteVideoStreamId} 
        scaleType={Voximplant.RenderScaleType.SCALE_FIT}/>

It is strictly required to handle the Voximplant.CallEvents.LocalVideoStreamAdded event to process a local video stream. Note that there is also the Voximplant.CallEvents.LocalVideoStreamRemoved event which notifies that a local video stream has stopped.

To process a remote video stream, there is a need to handle the Voximplant.EndpointEvents.RemoteVideoStreamAdded event; the Voximplant.EndpointEvents.RemoteVideoStreamRemoved event notifies that a remote video stream has stopped.

Mid-call operations

The most typical actions during a call – send video, hold a call, start receiving video (if video receiving was disabled on call start or answer) – are promise-based in React Native SDK (since version 1.0.0). In order to ensure successful execution of the appropriate methods, call them only after the Voximplant.CallEvents.Connected event is triggered.

See an example of the Voximplant.Call.sendVideo method usage below. The Voximplant.Call.hold and Voximplant.Call.receiveVideo methods are pretty similar:

async function sendVideo(doSend) {
    try {
        await call.sendVideo(doSend);
    } catch (e) {
        // e.code is one of the Voximplant.CallError enum constants
        console.warn(`${e.code} ${e.message}`);
    }
}

Voximplant.CallError contains all types of execution errors, such as “ALREADY_IN_THIS_STATE,” “MISSING_PERMISSION,” “TIMEOUT” etc.

Audio device management

Voximplant.Hardware.AudioDeviceManager API allows to:

  • get all available audio devices
  • get currently selected audio device
  • select audio device
  • handle active audio device changes and new audio devices (for example, Bluetooth headset or wired headset connection). These changes trigger the appropriate events.

All types of audio devices are represented in Voximplant.Hardware.AudioDevice enum.

Note that there are platform specific nuances in audio device management, see the details in the iOS and Android SDKs documentation.

To select an audio device:

Voximplant.Hardware.AudioDeviceManager.getInstance()
    .selectAudioDevice(Voximplant.Hardware.AudioDevice.SPEAKER);

In case of success the audio device changes, and the Voximplant.Hardware.AudioDeviceEvents.DeviceChanged event is triggered.

Camera management

Camera management is implemented as the Voximplant.Hardware.CameraManager class with the appropriate methods:

  • Voximplant.Hardware.CameraManager.switchToCamera
  • Voximplant.Hardware.CameraManager.setCameraResolution

This class also provides the ability to handle the result of camera switch and camera errors (currently on Android only).