This guide helps you to make your existing React Native project ready to use the reakt-native-toolkit
library.
To use the reakt-native-toolkit
library your project needs to support Kotlin Multiplatform.
Adding KMP to your project is very straightforward. You create a new module in your /android
project which is a so-called KMP shared module. Please refer to Kotlin's official guide on how to do this. The shared module will contain cross-platform code written in Kotlin and we will be able to expose classes within this code to React Native as native modules.
The shared module should be in a separate namespace like com.example.shared
. Going forward we assume that your shared module's directory is called shared
.
Make sure that in your settings.gradle
in the root directory the shared module is included. This should have been automatically added by the KMP wizard.
// settings.gradle
// ...
include ':shared'
For your shared module to use reakt-native-toolkit
we need to add it to its dependencies and setup KSP as described in the README. Make sure that you have completed the setup described there before continuing.
Since RN projects come with an iOS project that uses Cocoapods we configure our shared module to provide the compiled cross-platform Kotlin code to iOS via a Cocoapod.
First add the cocoapods
plugin to your shared module:
// android/shared/build.gradle.kts
plugins {
// ...
kotlin("native.cocoapods")
}
Configure the cocoapods
plugin:
// android/shared/build.gradle.kts
kotlin {
// ...
cocoapods {
name = "MyAppShared"
version = "0.1.0"
framework {
homepage = "..."
summary = "Shared Kotlin code for myapp"
baseName = "shared"
}
}
}
This will generate a MyAppShared.podspec
which we include in our iOS project:
# ios/Podfile
target 'MyRNProject' do
# ...
pod 'MyAppShared', :path => '../android/shared/MyAppShared.podspec'
end
After that run pod install
in the ios
directory.
To register the generated native modules e.g. in your app's MainApplication
you need to include the shared module in your app module:
// android/app/build.gradle
dependencies {
implementation project(':shared')
}
If you do not have one already, create a new RN package in your app module. This package will be used to register the generated native modules.
// android/app/src/main/java/com/example/MyRNPackage.kt
import com.myrnproject.shared.MyFirstRNModuleAndroid
class MyRNPackage : ReactPackage {
private val coroutineScope = CoroutineScope(Dispatchers.Default)
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
return listOf(
MyFirstRNModuleAndroid(reactContext, coroutineScope)
)
}
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<View, ReactShadowNode<*>>> {
return emptyList()
}
}
Add this package to getPackages
in your MainApplication
:
// android/app/src/main/java/com/example/MainApplication.kt
override fun getPackages(): List<ReactPackage> {
val packages: MutableList<ReactPackage> = PackageList(this).packages
// ...
packages.add(MyRNPackage())
return packages
}
It is easier to wrap your generated IOS RN native modules in a Kotlin class in the iosMain
source set of the shared module. This way to you can do dependency injection more easily and setup the coroutine scope directly from Kotlin.
// android/shared/src/iosMain/kotlin/com/example/shared/IOSRNModules.kt
import com.myrnproject.shared.MyFirstRNModuleIOS
class IOSRNModules {
private val coroutineScope = CoroutineScope(Dispatchers.Default)
fun createNativeModules(): List<RCTBridgeModuleProtocol> {
return listOf(
MyFirstRNModuleIOS(coroutineScope),
)
}
}
Then you can use this class to register the native modules in your iOS project using extraModulesForBridge
:
// ios/MyRNProject/AppDelegate.mm
#import <shared/shared.h>
@implementation AppDelegate
// ...
- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
{
return [[[SharedIOSRNModules alloc] init] createNativeModules];
}