How to Port Your Native Modules into a React Native Environment

As you probably know, React Native is a cross-platform development framework rapidly gaining followers. If you have a native SDK (an SDK written in Objective-C, Swift, or Java), you might find yourself requesting a React Native version in the near future. This article can serve as a guide to port your native modules into a React Native environment.

Branch realized this quickly, as a lot of our existing partners created new projects in React Native. We didn’t have the resources needed to design and implement a React Native component from scratch, so we solved it by leveraging our core Native SDKs, and wrapping them with packaged tools like NativeModules to make porting a breeze.

To begin, you must consider three high-level components when porting your existing native library into React:

  • The actual native files your native library interacts with
  • The middleware object that shuttles messages between native and Javascript
  • The Javascript interface you give to your end-users: React Native devs.

For this post, we’ll use iOS examples, but the same high-level concepts apply to Android.

Let’s start with the middleware component since that’s where the “magic” happens when coordinating between Objective-C and Javascript. We start by creating an object that implements the RCTBridgeModule protocol. By implementing this protocol, the Javascript layer gets access to functions defined in the middleware. Additionally, this middleware object–written in Objective-C–can interface with other Objective-C code, thereby letting us wrap around our existing native SDK calls, like initNewUserSession. In the example below, notice how these functions in the middleware mirror exactly what our native SDK provides:

Import Foundation

The React Native side will be exposed to these functions, which will connect to our native SDK code.

Now that we have a nice middleware object, we need the Objective-C environment to be aware of it. For those familiar with iOS programming, this means we invoke RNBranch in AppDelegate.m. What’s very nice about this design pattern is that by having the wrapper simply wrap around the SDK, we’re letting the native SDK do the heavy lifting of lifecycle management, but allowing ourselves the flexibility to design the interface back to Javascript:

Javascript

RNBranch initializes and invokes the Branch SDK. To the Javascript side, it just works.

Once we know we can hook into the iOS lifecycle methods and have the middleware “listen” to these lifecycle events, we can write the Javascript portion of the SDK to receive notifications when an event occurs. For developers using React Native with Branch, it’s a matter of tapping into the Javascript function that connects to the RNBranch methods, and doing all the cool things they do with Branch, like receive deep link data, save custom events, and create shareable links, without having to worry about messy or complicated hooking into native code.

JS Environment

The middleware object brought into a JS environment

Because we implemented the necessary protocol, calling functions into Objective-C is straightforward:

Objective C Function

Invoking the function on the middleware object

What if you want to go the other way, and listen to incoming events from Objective-C? Using the native events library found in React, you can simply register event names and callbacks that are defined in the middleware object. Once the event emits, we’ll know about it.

ReactNative

nativeEventEmitter is a package bundled with ReactNative

Branch found a relatively straightforward way to port into React Native without spending a bunch of time re-writing the Native SDK into a Javascript environment. We hope this helps you set your Native SDKs up in React Native, as well, and provides you with a clean and flexible way of reusing your code to empower React Native developers. Want to get started with Branch? Sign up for the Branch dashboard here.