Home
Services
Products
Projects
Who We Are
Blogs
Contact Us
Building Cross-Platform React Native Bridges for iOS and Android
React Native's strength lies in its ability to bridge the gap between JavaScript and native platforms (iOS and Android). This "bridge" facilitates communication, enabling developers to leverage existing native libraries within their React Native applications. This capability is crucial for building production-ready apps with enhanced performance and access to platform-specific features. This article provides a comprehensive guide to creating native bridges that work seamlessly across both iOS and Android, allowing you to harness the power of Swift/Objective-C and Java within your React Native projects.
To illustrate the concept, we'll build a simple "LightApp" using the react-native CLI. This app will demonstrate how to control a virtual "Bulb" through a native bridge. The same React code will function on both platforms, showcasing the cross-platform nature of this approach.
react-native init LightApp
cd LightApp
This section focuses on building a bridge between Swift/Objective-C and your React Native component. The process involves three key steps:
First, within Xcode, create a new Swift file named Bulb.swift
. Also, create a bridging header file (if one doesn't already exist) named LightApp-Bridging-Header.h
. This header file allows communication between Swift and Objective-C. Add the following line to the bridging header:
#import <React/RCTBridgeModule.h>
This import provides the necessary interface for bridging.
Next, update Bulb.swift
with the following 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've created a Bulb
class inheriting from NSObject
, making it compatible with Objective-C. The @objc
annotation exposes the class and the turnOn
function to Objective-C and subsequently to React Native.
Now, update App.js
to access the Bulb class:
import React, { Component } from 'react';
import { Text, View, NativeModules, TouchableOpacity, StyleSheet } from 'react-native';
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}>
<Text>Turn On</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
});
Running the app and checking the Xcode console will confirm that the Swift turnOn method is called from JavaScript.
You might encounter warnings related to running native code on the wrong thread. To ensure the native module runs on the main queue, add the following to Bulb.swift
:
@objc static func requiresMainQueueSetup() -> Bool {
return true
}
To display the bulb's status in the app, add a getStatus
function to Bulb.swift
:
@objc func getStatus(_ callback: RCTResponseSenderBlock) {
callback([NSNull(), Bulb.isOn])
}
This function takes a callback and returns the isOn
value. Update App.js
to utilize this:
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 });
});
};
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome to Light App!!</Text>
<TouchableOpacity onPress={this.turnOn}>
<Text>Turn On</Text>
</TouchableOpacity>
<Text>Bulb is {this.state.isOn ? "ON" : "OFF"}</Text>
</View>
);
}
Now, let's create the equivalent functionality for Android. Create a Java class named Bulb.java
within the Android project and add the following code:
package com.lightapp; // Replace with your app's package name
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 isOn = false;
public Bulb(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "Bulb";
}
@ReactMethod
public void turnOn() {
isOn = true;
System.out.println("Bulb is turned ON");
}
@ReactMethod
public void getStatus(Callback successCallback) {
successCallback.invoke(null, isOn);
}
}
Next, create a Java class named BulbPackage.java
and add the following code to register the module:
package com.lightapp; // Replace with your app's package name
import com.facebook.react.ReactPackage;
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 BulbPackage implements ReactPackage {
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new Bulb(reactContext));
return modules;
}
}
Finally, you need to register the BulbPackage
in your MainApplication.java
file. Import your BulbPackage
class, and add it to the getPackages
method:
// ... other imports
import com.lightapp.BulbPackage; // Import your BulbPackage
public class MainApplication extends Application implements ReactApplication {
// ... existing code ...
@Override
protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackagesList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
packages.add(new BulbPackage()); // Add this line
return packages;
}
// ... existing code ...
}
The same JavaScript code used for iOS will work for Android as well, demonstrating the cross-platform compatibility of the bridge.
By following these steps, you can effectively create and utilize React Native bridges, unlocking the potential of native functionalities within your cross-platform applications. This allows you to build richer, more performant apps that leverage the best of both worlds. Remember to rebuild your app after making native code changes for them to take effect.
Defx, with its extensive experience in IT services, can help you navigate the complexities of React Native development and create robust, high-quality cross-platform applications.
See More
Contact Us
Let’s make your Idea into Reality
Let's Talk
© Copyright DEFX. All Rights Reserved
GoodFirms ★ 4.2
Clutch ★ 4.2
Google ★ 4.2