How to Create Bridge in React Native for iOS and Android?

Jul 28 2020Written by Manektech Team

What is React Native Bridge?

React Native is developed in such a way that we will create a bridge between the language and therefore the JavaScript code. A “bridge” is nothing but how to line up communication between native platform and React Native.

One of the most important reasons for the recognition of React Native app development is that we can create a bridge between the language and JavaScript code, which suggests we will reuse all the reusable libraries created in the iOS and Android world.

To create a production grade application at some point of your time you would like to use Native Bridge. There are only a few articles and tutorials on cross-platform React Native bridge which works on both iOS and Android. During this article, we'll create a Native Bridge to access Swift and Java class from JavaScript.

Create the LightApp

To better understand Native Modules we'll create an easy LightApp example using react-native CLI.

$ react-native init LightApp

$ cd LightApp

Next, we'll create a category Bulb in Swift for iOS and Java for Android, and this may be utilized in this app during a React component. This may be a cross-platform example and therefore the same React code will add both iOS and Android.

As we've created a basic skeleton of the project, next we've divided this text into two sections:

Section 1 — Native Bridge in iOS

Section 2 — Native Bridge in Android

Section 1 — Native Bridge iOS
In this section, we'll specialise in iOS and make a bridge between Swift/Objective C and your React Component. it's these three steps:
Step 1 - Create a Bulb class and Bridge Header
Step 2 - Understanding GCD Queue and fixing the warning:
Step 3 - Accessing a variable in JavaScript from Swift and Callbacks

Step 1 - Create a Bulb class and Bridge Header

To get started we'll create a Bulb class in swift, which can have a static class variable isOn and a couple of other functions. then we'll access this swift class from Javascript. Let's start by opening LightApp.xcodeproj in the ios folder. It should open Xcode together with your ios code.
Once you open the project in Xcode, then create a replacement Swift file Bulb.

We have also clicked on Create Bridging Header which can create a file LightApp-Bridging-Header.h this may help to speak between Swift and Objective C code. Remember that during a project we've just one Bridge Header file. So if we add new files, we will reuse this file.
Update following code in LightApp-Bridging-Header.hfile:

#import “React/RCTBridgeModule.h”

RCTBridgeModule will arrange an interface to join a bridge module.
Next update Bulb.swift with the subsequent code:

Import Foundation

@objc(Bulb)

Class Bulb : NSObject {
@objc
Static var isOn = false

@objc

Func turnOn(){

Bulb.isOn = true

Print (“Bulb is now ON”)

}

}

We have created a Bulb class which is inherited from NSObject. The base class of most Objective-C class ranking is NSObject, from which subclasses acquire a basic interface to the runtime system and therefore the capability to behave as Objective-C objects. we will see that we've used @objc before a function and sophistication , this may make that class, function or object available to Objective C

React Native won't expose any function of Bulb to React JavaScript unless explicitly done. to try to do so we've used RCT_EXPORT_METHOD() macro. So we've exposed the Bulb class and turnOn function to our Javascript code. Since Swift object is converted to Javascript object, there's a kind of conversation. RCT_EXPORT_METHOD supports all standard JSON object types:

NSString to string

NSInteger, float, double, CGFloat, NSNumber to number

BOOL to boolean

NSArray to array

NSDictionary to object with string keys and values of any type from this list

RCTResponseSenderBlock to function

Now let’s modernize JavaScript code and approach this Bulb class from our React component. to try to to so open App.js and update with the subsequent code:

Export default class App extends Component{

turnOn = () => {

NativeModules.Bulb.turnOn();

}

render(){

return(

<View style = {styles.container}>

<Text style = {styles.welcome}> Welcome to Light App !! </Text>

<TouchableOpacity onPress = {this.turnOn}>

</TouchableOpacity>

</View>

);

}

}

const styles = StylesSheet.create ({

container : {

flex :1,

justifyContent : ‘center’,

alignItems : ‘center’,

backgroundColor : ‘#F5FCFF’,

},

});

})

Now open Xcode console to ascertain the logs and that we can see that Swift turnOn method is named from JavaScript code. (As we've done logging within the method)

Step 2 - Understanding GCD Queue and fixing the warning:

Now let's fix the warning shown at rock bottom of the simulator and in browser console:

To understand it better let's understand about all the thread React Native runs:

Main thread: where UIKit work

Shadow queue: where the layout happens

JavaScript thread: where your JS code is really running

Every native module has its own GCD Queue except it determines otherwise. Now since this Native module will run on a special thread and our main thread depends thereon , it's showing this warning. And to form this code to run on MainQueue, open Bulb.swift and add this function.

@objc

static func requiresMainQueueSetup() -> Bool {

return true

}

You can explicitly mention return false to run this during a separate threat.

Step 3 - Accessing a variable in JavaScript from Swift and Callbacks

add the Bulb Status(ON or OFF) value to our React screen. to try to do so we'll add the getStatus function to Bulb.swift and call that method from JavaScript code. we'll create this method as a callback.

Let's update the code in bold in Bulb.swift

Import Foundation

@oblc(Bulb)

Class Bulb :NSObject {

@objc

Static var isOn = false

@objc

Func turnOn () {

Bulb.isOn= true

Print (“Bulb is now ON”)

}

@objc

Func turnOFF(){

Bulb.isOn = false

Print (“”print Bulb is now OFF”)

}

@objc

Func getStatus(_ callback : RCTResponseSenderBlock){

callback  ([NSNull(),Bulb.isOn])

}

@objc

Static func requireMainQueueSetup() -> {

return true

}

}

getStatus() method receives a callback parameter that we'll pass from your JavaScript code. and that we have called the callback with an array of values, which can be exposed in JavaScript. we've passed NSNull() because the first element, which we've considered as a mistake within the callback.

And then finally update the React Code:

Import React , {Component} from ‘react;

Import {Text,View,NativeModules,TouchableOpacity} from ‘react-native;

Export default class App extends Component {

constructor(props){

super(props);

This.state = {isOn : false};

this.updateStatus();

}

turnOn =() => {

NativeModules.Bulb.turnOn();

this.updateStatus();

updateStatus = () => {

NativeModules.Bulb.getstatus((error,isOn ) => {

this.setState({ isOn : isOn)};

)}

}

render(){

return(

<View>

Welcome to Light App !!

Bulb is {this.state.isOn ? “ON” : “OFF”}

{!this.state.isOn ? <TouchableOpacity>

<Text style = {{color : “#FF6347”}}> “Turn ON”

</Text>

</TouchableOpacity>:

<TouchableOpacity>

<Text style ={{color :”#FF6347}}>”Turn OFF”

</Text>

</TouchableOpacity> } </View>

);

}

}

Rebuild the code and run the app, you'll see the Bulb Status value and once you click on activate then it'll show Bulb is ON

Do remember to rebuild the code rather than refresh, as we changed Native Code.

Section 2 — Native Bridge in Android

In this section, we'll make an equivalent Javascript code which we return for iOS to figure with Android. At this point we'll create a Bulb class in Java and expose an equivalent function turnOn, TurnOff and getStatus to Javascript.

Open Android Studio and click on Open an existing Android Studio project then select the android folder inside our LightApp. Once all gradle dependency is downloaded, create a Java Class Bulb.java as shown:

And update the subsequent code in Bulb.java:

Import com.facebook.react.bridge.Callback;

Import com.facebook.react.bridge.ReactApplicationContext;

Import com.facebook.react.bridge.ReactContextBaseJavaModule;

Import com.facebook.react.bridge.ReactMethod;

Public class Bulb extends ReactContextBaseJavaModule {

Private static Boolean inOn = false;

Public Bulb (ReactApplicationContext reactContext) {

Super (reactContext);

}

@ReactMethod

Public void getStatus (

Callback successCallback){

successCallback.invoke ( null,isOn);

}

@ReactMethod

Public void turnOn (){

isOn = true ;

system.out.println(“Bulb is turn On ”);

}

@ ReactMethod

Public void turnOff (){

isOn = false;

system.out.println(“Bulb is turn OFF”);

}

@Override

public  string getName (){

Return : ‘Bulb’;

}

}

We have created a Bulb Java class which is rooted from ReactContextBaseJavaModule. ReactContextBaseJavaModule requires that a function called getName is usually implemented. The aim of this method is to return the string name of the Native Module which represents this class in JavaScript. So here we'll call this Bulb in order that we will access it through React.NativeModules.Bulb in JavaScript. rather than Bulb, we will have a special name also.

Not all functions are exposed to Javascript explicitly, to show a function to JavaScript a Java method must be annotated using @ReactMethod. The return sort of bridge method is usually void.

We have also created a getStatus function which has params as callback and it returns a callback and passes the worth of static variable isOn.

Next step is to register the module, if a module isn't registered it'll not be available from JavaScript. Create a file by clicking on Menu File -> New -> Java Class and therefore the filename as BulbPackage then click OK. then add following code to

package com.bridgeapp;

Import com.facebook.react.bridge.Callback;

Import com.facebook.react.bridge.ReactApplicationContext;

Import com.facebook.react.bridge.ReactContextBaseJavaModule;

Import com.facebook.react.bridge.ReactMethod;

 class Bulb extends ReactContextBaseJavaModule {

Private static Boolean inOn = false;

Public Bulb (ReactApplicationContext reactContext) {

Super (reactContext);

}

@ReactMethod

Public void getStatus (

Callback successCallback){

successCallback.invoke ( null,isOn);

}

@ReactMethod

Public void turnOn (){

isOn = true ;

system.out.println(“Bulb is turn On ”);

}

@ ReactMethod

Public void turnOff (){

isOn = false;

system.out.println(“Bulb is turn OFF”);

}

@Override

public  string getName (){

Return : ‘Bulb’;

}

}

We demand to Override createNativeModules function and compute the Bulb object to the modules array. If this is often not added here then it'll not be available in JavaScript.

We don’t have to change any JavaScript code written in iOS, as we've exposed an equivalent class name and performance . If you've got skipped the iOS part then you would like to repeat the React Javascript code from App.js

Now run the App over Android Studio or from react-native run-android:

We can detect the Bulb status on the screen and may turn on or distant from the button. The good thing is that we've created a Native Bridge which is Cross Platform.

Develop robust native-style applications for both Android and iOS with the help of top rated React Native development company. React Native mobile applications for both iOS and Android platform. Since it requires to be coded only once, React Native quickly gained popularity amongst developers as well as businesses because of its fast time to market and cost-effectiveness.

Contact us

Here to Help ambitious people TRANSFORM the Digital Solutions!