Creating a custom Swrve bridge for React Native.

Douglas.

React Native Engineer


For what reason?

Well… I’m glad you asked. Because we love building new shiny things here at Reason. But also to our surprise there wasn’t a library out there that fulfilled our need. There is react-native-swrve, which does a fantastic job of integrating Swrve SDK with React Native. However, we discovered that the library sends generic events prefixed with the word “action.” to all our events... there’s our blocker.

Rather than fork, make private and modify react-native-swrve, we decided to go back to basics on this one and create our own Native bridge module because simplicity is the best thing in life (speaking like a true minimalist).

Getting started

Follow this guide and build your own React Native bridge module specifically for Swrve, but also use this as a base to create your own bespoke native bridge module.

I, as many before me, started with a simple toast module. I recommend reading the guide on Native Modules, it’s the perfect base to get you started on bridging JS and Native code in React Native. Kudos to the React Native team for their improved docs.

Right! Let’s get this show on the road.

  1. Install the Swrve Android SDK
  2. Create CustomSwrveModule.java inside android/app/src/main/java/com/your-app-name
// CustomSwrveModule.java

package com.reason.wse.staging;

import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.swrve.sdk.SwrveIdentityResponse;
import com.swrve.sdk.SwrveSDK;

import java.util.Iterator;
import java.util.Map;
import java.util.HashMap;
import android.util.Log;

import org.json.JSONObject;

public class CustomSwrveModule extends ReactContextBaseJavaModule {

  public CustomSwrveModule(ReactApplicationContext reactContext) {
    super(reactContext);
  }

  @Override
  public String getName() {
    return "CustomSwrveModule";
  }

  @ReactMethod
  public void sendEvent(String eventName) {
    SwrveSDK.event(eventName);
  }

  @ReactMethod
  public void sendEventWithPayload(String eventName, String jsonPayload) {
    try {
      HashMap<String, String> map = new HashMap<String, String>();
      JSONObject jObject = new JSONObject(jsonPayload);
      Iterator<?> keys = jObject.keys();

      while( keys.hasNext() ){
        String key = (String)keys.next();
        String value = jObject.getString(key);
        map.put(key, value);
      }

      SwrveSDK.event(eventName, map);
    }
    catch (Exception e) {
      Log.e("Swrve", "Failed to create event payload HashMap", e);
    }
  }
}
  1. Create CustomSwrvePackage.java inside android/app/src/main/java/com/your-app-name
// CustomSwrvePackage.java

package com.reason.wse.staging;

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 CustomSwrvePackage 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 CustomSwrveModule(reactContext));

    return modules;
  }
}
  1. Add new CustomSwrvePackage() inside your MainApplication.java file
// MainApplication.java

package com.reason.wse.staging;

...

import com.reason.wse.staging.CustomSwrvePackage; // <-- Add this line with your package name.

...

public class MainApplication extends Application implements ReactApplication {
    ...
    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
            ...
            new CustomSwrvePackage()  // <-- Add this line with your package name.
      );
    }
    ...
}

That’s it for the Native stuff! Now back to our trusty Javascript next.

  1. Add SwrveModule.js inside src/modules (create a /modules folder inside your JS src folder)
// SwrveModule.js

/**
 * This exposes the native CustomSwrveModule as a JS module. This has a
 * function 'sentEvent' which takes the following parameters:
 *
 * 1. String eventName: A string with the swrve event name
 */
import { NativeModules } from 'react-native';

module.exports = NativeModules.CustomSwrveModule;

This file imports NativeModules from React Native and exports our native custom Swrve module we created in all previous steps above.

  1. Last but not least, let’s use our native bridge module! Be ready for some AWE! Import SwrveModule from ‘../modules/SwrveModule.js’ in whichever file you need to use Swrve in.

Call

// Import SwrveModule in file where it is needed

import SwrveModule from '../modules/SwrveModule';

...

// To send an event with name

SwrveModule.sendEvent('EVENT_NAME');

// To send an event with name and Object payload

SwrveModule.sendEventWithPayload('EVENT_NAME', JSON.stringify({ some_key: 'some_value' }));

Wah hey! You’ve just created and used your native bridge SwrveModule! But wait a minute, where our my events? Swrve makes it a breeze.

Login to your Swrve dashboard -> Under Analytics -> Events You should eventually see your events log here.


Please note: You may need to import your event names into Swrve dashboard itself. Also bear in mind events could take up to 60 minutes to show up here.


If you would like to see events in real-time for debugging purposes Swrve has a QA device section.

Settings -> QA Devices -> Add QA Device.

Once you’ve added a QA Device, click on the very right icon labelled Logging. Here you’ll be able to view listened events sent from CustomSwrveModule.java.

There you have it folks, simple wasn’t it?! We’d love to hear your feedback and challenges you’ve faced while creating your own React Native bridge module.

Thanks for reading! Happy coding JS!


Further Reading

Hanna - 2019-04-09

Join us at London's biggest serverless conference

After two days of workshops on 9th & 10th, the conference will run as a single track on all things serverless on 11th July. We'll be there - we hope you will too!

Amale Ghalbouni - 2019-02-26

The road to Oscar nomination.

When we worked with Guardian Documentaries in 2018 one of their stated aims was to win an Oscar - we're psyched to see them nominated already!