Intergration RN UI/app into native android/ios project

Viewed 92

I am working on SDK for android and later for ios. And this SDK should be added to the native android project as AAR and probably for ios as a pod.

I was following RN article integration with existing apps and it is working completely fine but my problem is I don't want to run the whole activity up to the native project... I just need to open modal dialog with RN components and some logic

The third part of application write in Kotlin on android implementing my SDK

class MainActivity : AppCompatActivity() {
...
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val MySDK = MySdk(this, this, 'some other data')
        ...
        btnOpenWalleePaymentModalReactNative.setOnClickListener {
            MySDK.launchDialog()
        }

and now my SDK opening RN activity (inside MySDK):

class MySDK(private val context: Context, val activity: Activity) {

    fun launchDialog() {
        val intent = Intent(context, MyReactActivity::class.java)
        context.startActivity(intent)
    }

and this part open standard activity where all RN exist but i don't want to have an activity i want to have dialogue

so I created a class with dialogue what I want to use for that (BottomSheetDialogFragment)

class TestDialog(context: Context, var activity: Activity): BottomSheetDialogFragment() {
    private lateinit var reactRootView: ReactRootView
    private lateinit var reactInstanceManager: ReactInstanceManager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        SoLoader.init(context, false)
        reactRootView = ReactRootView(context)
        val packages: List<ReactPackage> = PackageList(activity.application).packages



        reactInstanceManager = ReactInstanceManager.builder()
            .setApplication(activity.application)
            .setCurrentActivity(activity)
            .setBundleAssetName("index.android.bundle")
            .setJSMainModulePath("index")
            .addPackages(packages)
            .setUseDeveloperSupport(BuildConfig.DEBUG)
            .setInitialLifecycleState(LifecycleState.RESUMED)
            .build()

        reactRootView?.startReactApplication(reactInstanceManager, "PaymentSDK", null)
        activity.setContentView(reactRootView)

    }

and when I init this class and open dialogue with react native it will change the activity from third party library and put there my react activity and blurred overlay from dialogue... TestDialog(context, activity ).show(activity.supportFragmentManager, "tag") like on the picture

enter image description here

any idea how to squeeze RN view/UI into fragment or dialogue view or any other idea how to do it? Or an article with something similar like writing an RN module for native android?

1 Answers

I've developed a RN native module as a bridge for a native SDK once. I've followed this old tutorial page https://archive.reactnative.dev/docs/native-modules-android.

From what I've understood from your situation, you will have a RN application trying to call a showDialog function from this native module, passing the RN activity to make sure it is opened from it, right? The snippets that you've posted confused me a little bit but I'll try to help with what I remember.

You'll have to have a JS/RN project for this native module, you can follow this https://reactnative.dev/docs/native-modules-setup and the following articles from the official docs to create it.

First, in the Android part of this created project you will need to have the .aar downloaded through gradle or locally in the project.

The Android part will have two important files: MySdkPackage and MySdkModule

MySdkPackage will just list your module for React Native to see it, something like:

package com.reactnativemysdk

import java.util.Arrays
import java.util.Collections

import com.facebook.react.ReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ViewManager
import com.facebook.react.bridge.JavaScriptModule

class MySdkPackage : ReactPackage {
    override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
        return Arrays.asList<NativeModule>(MySdkModule(reactContext))
    }

    override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
        return emptyList<ViewManager<*, *>>()
    }
}

and MySdkModule will indeed make the connection with your Android native .aar implementation, having a reference from the React Native context and activity. Something like:

package com.reactnativemysdk

class MySdkModule(private var reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {

  @ReactMethod
  fun showMyDialog(promise: Promise) {
    if (reactContext.hasCurrentActivity()) {
        reactContext.currentActivity?.runOnUiThread {
        MySdk.getInstance().showDialog(reactContext.currentActivity) //this activity and context are the references that 
        // you need to properly show the dialog as it was native
      }
    } else {
      promise.reject(ERROR_STRING, "No activity found.")
    }
  }

}

this method annotated with @ReactMethod will need a JS counterpart, where things will be tied together and you will be able to call this JS 'bridge' code from your RN app JS code

the JS bridge will be something like this (the example I did was in TypeScript so I'm sorry):

import { Platform, NativeModules } from 'react-native';

type MySdkInterface = {

  showMyDialog(): Promise<void>;

const { MySdk } = NativeModules;

export default MySdk as MySdkInterface;

Creating this native module and organizing things like this you will have a better integration between and RN and the native parts and you will be able to properly show the dialog and any rendering/layout issues would be solvable in your original Android SDK code

So you will have something like

RN App JS showDialog <-> RN Native Module JS showDialog <-> RN Native Module Android (or iOS) native code showDialog <-> MySdk (the .aar one) showDialog implementation

I'm pretty sure these links and references will be able to help you as well but I hope I was able to at least clarify the way for you

I'd recommend following the first link, the https://archive.reactnative.dev/docs/native-modules-android, and following and understanding this ToastModule structure, I think the most recent one doesn't help that much.

Related