React Native

React-Native Bridging with Native Code (Android/iOS)

Abstract:

React-native keeps on enhancing itself to meet desired functionalities for end users. This is to help developers by many ways to achieve native functionality and Bridging is one of its capabilities which helps to achieve native functionality by java script code.

Introduction:

React Native is a framework for mobile applications (Android, iOS and UWP), developed by Facebook and announced in 2015. It used the existing “React architecture” for mobile apps, bringing Component-based interaction to mobile application elements. Like React, React Native is also based upon JavaScript, and react native developers can build mobile apps by simply using JavaScript.

React Native Bridging is a concept that was developed by the React team to help the mobile app developers build their own custom modules, if not provided by the default Components given by React.

Why do we need React Native Bridging ?

React Native provides developers with a variety of modules which developer can use to create functionality in the application. For example, React Native provides its own “NetInfo” module to check for Internet Connectivity in applications. However, sometimes an app needs access to a platform API for which React doesn’t have a module yet. Or maybe the app needs a custom functionality which cannot be achieved using default React Native modules.

Hence, React Native Team allows us to write Native Code (Android and iOS) and communicate between native code and React Native JavaScript code to achieve custom developed functionality.

According to the documentation, React Native team believes that if React Native doesn’t support a native feature that you need, you should be able to build it yourself by using Bridging.

How bridging works internally – Bridging Native Modules Example:

Let us build a small project that will use the concept of Bridging Native Code and React Native JavaScript code to use the native functionality.

Project Prerequisites:

To be able to run a project as per example given, following should be the system prerequisite.

● Node.js (runtime environment)
● React Native CLI (command line interface).
● Android Studio/Xcode

Once all these have been installed, you can verify their installations and begin working on the project as explained below.
For this project, I will be using the following environment –

● Ubuntu 18.04 LTS(Android)/Mac OS(iOS)
● Node.js version - 10.7.0
● NPM version - 6.1.0
● React Native Version - 0.56.0 (stable)
● react-native-cli version - 2.0.1
● Android Studio Version - 3.1.3 (stable)(Android)/Xcode(iOS)

React Native Bridge Module: Hello World

Create an empty folder named react-native-helloworld, you can initialize the project via react-native command:
$ react-native init helloworld
$ cd helloworld
There is a package.json file generated, and the project directory structure is created as well.
Here is my project structure:
- Project folder - root of the project
- Package.json - a file that specifies project configuration and dependencies.
- ios - a folder that contains native code (Objective c or swift) for iOS.
- android - a folder that contains Java code for native module
- Index.js - entry file for React Native Project

iOS:

Here is a simple example for printing message in console by native code

Step 1: Create a native file from your project in Xcode by the right click on your project folder->New File->iOS->Cocoa Touch class and enter your custom module name like I am using CustomMessage.

Step 2: Add code in newly created module, RCTBridgeModule is using to communicate with React Native so need to include in header file-file (.h)

CustomMessage.h

#import <React/RCTBridgeModule.h>

CustomMessage.m
#import “CustomMessage.h”
#import “React/RCTLog.h”
@implementation CustomMessage
// This RCT (React) “macro” exposes the current module to JavaScript
RCT_EXPORT_MODULE();
// We must explicitly expose methods otherwise JavaScript can’t access anything
RCT_EXPORT_METHOD(printMessage)
{
RCTLogInfo(@”Custom Message”);
}
@end
Step 3:
Use in React Native javaScript code:
import { NativeModules } from ‘react-native’;
var nativeModule = NativeModules.CustomMessage;
nativeModule.printMessage();

Android:

In our Android application, we were using Firebase for handling silent notifications. Since our application was user-based, the notifications were not meant to be shown when the user was logged out. But all the login functionality was implemented in React Native, whereas Firebase code was written in Java (Android). Thus, we needed a way for the React code to inform the Java code about the user’s login actions (logged in or logged out). For that purpose, React Native Bridging was used.
First, we’ll create our custom module in our android project. The steps for the same are explained below –

Step 1: Create a class that extends ReactContextBaseJavaModule to be used as bridging module. We will export this method to React Native via NativeModules API and will use one of it’s methods in our React code.

public class FirebaseNativeModule extends ReactContextBaseJavaModule
{ …

Step 2: Create a method that overrides ReactMethod interface. In this method, we receive an argument “isLoggedIn” from the code and save its value to SharedPreferences local storage to be used throughout the application.

@ReactMethod
public void setUserLoggedIn(boolean isLoggedIn)
{
SharedPreferences pref = …;
SharedPreferences.Editor editor = pref.edit();
editor.putBoolean(“isLoggedIn”, isLoggedIn);
editor.commit();
}

Step 3: Now create a ReactPackage class to wrap the module in.

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MyPackage implements ReactPackage {

public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}

@Override
public List createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}

@Override
public List createNativeModules(
ReactApplicationContext reactContext) {
List modules = new ArrayList<>();
modules.add(new FirebaseNativeModule(reactContext));
return modules;
}}

Step 4: In your MainApplication class, use the new package that you created in the previous step so that React Native can use it –

public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List getPackages() {
return Arrays.asList(
new MainReactPackage(),
new MyPackage()

Now we need to use this module in our React Native code.
For this, we will make changes to our JavaScript code.

Step 5: Create a new JavaScript file “FirebaseNativeModule” in your React project –

‘use strict’;
import { NativeModules } from ‘react-native’;
module.exports = NativeModules.FirebaseNativeModule;

Step 6: Now we can use this module anywhere in our React Native code. For example, when user clicks logout button, we can invoke the native module function as shown below –

FirebaseNativeModule.setUserLoggedIn(false);

This invokes the “setUserLoggedIn” method in Step 2.

Thus, this is how we can communicate between React Native JavaScript code and Java Code.

About Author:

Qss author image About Author: Manoj Kumar Sharma , Team Lead in QSS technosoft Pvt. Ltd. I am having 3+ year experience in web development using javascript/PHP and 1.5 year experience in cross platform mobile apps development using React Native.

About QSS:

QSS has a proven track executing React Native based cross platform mobile applications for its esteemed customers. The company has a core competency in developing and delivering Enterprise level React Native applications both in on Native and Hybrid platforms. The React Native competency has experienced and dedicated team of React Native developers. To Know More...