# Link SDKs in React Native In this guide we will walk you through the steps to integrate the Link SDKs in a React Native context. You can integrate Enode’s Link SDKs for iOS and Android into your React Native app by making them accessible through the [Native Modules](https://reactnative.dev/docs/native-modules-intro) system. Using this guide, you will: 1. Ensure that you have the prerequisites to get started 2. Expose the Link SDKs in iOS and/or Android as native modules 3. Import the exposed native modules into your React Native app ## Prerequisites - An existing React Native application - Existing iOS or Android projects within your React Native app - A server that calls [Link User](https://developers.enode.com/api/reference#postUsersUseridLink) with API version `2024-01-01`. You should be able to generate a `linkToken` to pass back to your React Native client Expo apps: Expo users may have to migrate to using [development builds](https://docs.expo.dev/workflow/customizing/) in order to add custom native code. If `/ios` or `/android` folders don’t exist in your project, you might have to run `npx expo run:ios` and `npx expo run:android` first. For more details, see the [Expo docs](https://docs.expo.dev/workflow/customizing/).The [`expo-enode-link-sdk` Expo Module](https://github.com/YoussefHenna/expo-enode-link-sdk) is also available from the open source community, which you can use instead of following this guide. (Enode is unaffiliated with the creator nor do we maintain the module.) ## Implement the iOS native module ### Set up your Xcode project Open the iOS project in your React Native app (found under `/ios/*.xcworkspace`) in Xcode. Follow the [Set up your Xcode project](https://developers.enode.com/docs/link-sdks/ios) steps from our iOS SDK guide to add LinkKit by extracting the SDK archive, importing the framework, and configuring Bluetooth access. ### Set up a native module (iOS) #### Create the Swift implementation file In your main iOS project folder (next to AppDelegate), create a file called `LinkUIModule.swift`. #### Create a bridging header At this point, Xcode may prompt you to create a bridging header since you are about to mix Swift and Objective-C (it also may already exist). If it does not exist, manually create one called `YourProjectName-Bridging-Header.h` in that same project folder. Ensure the file contains the following: ```swift // YourProjectName-Bridging-Header.h #import "React/RCTBridgeModule.h" ``` #### Implement the SDK in Swift Back in `LinkUIModule.swift`, add your implementation: The bulk of this is the reference implementation from the [iOS Link SDK](https://developers.enode.com/docs/link-sdks/ios) guide alongside some React Native specific details: ```swift // LinkUIModule.swift import Foundation import LinkKit @objc(LinkUIModule) class LinkUIModule: NSObject { private var handler: Handler? @objc static func requiresMainQueueSetup() -> Bool { return true } @objc func show(_ token: String, callback: @escaping RCTResponseSenderBlock) { let vc = RCTPresentedViewController() self.handler = Handler(linkToken: token) { (code: LinkResultCode, errMsg: String?) in callback([ code.rawValue, errMsg as Any ]) } self.handler?.present(from: vc!) } } ``` - `requiresMainQueueSetup` implemented to return `true` to tell React Native to initialize the module on the main thread - Adding and invoking a `callback` in the `handler`'s completion handler, whose argument will be available in JavaScript - Presenting LinkKit UI from the instance of `RCTPresentedViewController()` #### Expose your Swift implementation to React Native Create a new file called `LinkUIModule.m` and add the following. This makes your Swift implementation available in JavaScript and tells React Native to use the main queue when calling your method since it involves UI operations. ```objectivec // LinkUIModule.m #import "React/RCTBridgeModule.h" @interface RCT_EXTERN_MODULE(LinkUIModule, NSObject) - (dispatch_queue_t)methodQueue { return dispatch_get_main_queue(); } RCT_EXTERN_METHOD(show:(NSString *)token callback:(RCTResponseSenderBlock)callback) @end ``` ## Implement the Android native module ### Import the SDK to your project Open the Android project in your React Native app (found under `/android`), ideally in Android Studio. Follow our [Android SDK guide](https://developers.enode.com/docs/link-sdks/android) to include the SDK in your app’s `build.gradle`. (In a React Native app, you should add the dependency in `/android/app/build.gradle`.) ### Configure your project #### SDK versions If necessary, you may have to increase your compile SDK version and your minimum SDK version. For example, in `/android/gradle.properties` set: ```properties android.compileSdkVersion=34 android.minSdkVersion=24 ``` #### Kotlin + Java If your app has a mix of Java and Kotlin, you'll also need to configure your project to support both. Add this to your `/android/app/build.gradle` (after you declare your `dependencies`): ```groovy apply plugin: "kotlin-android" ``` Then add this to you `/android/build.gradle`'s: ```groovy dependencies { ... classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" } ``` #### Styles The Link SDK makes use of a few style attributes. Follow the guide for our [Android SDK](https://developers.enode.com/docs/link-sdks/android) to ensure that you are defining and applying your styles to avoid theming errors. ### Set up a native module (Android) #### Create the Kotlin implementation file Create a new Link UI module file as a Kotlin class within your Android project under `/android/app/src/main/java/com/your-app-name/LinkUIModule.kt`. This contains the main native implementation of our Link SDK. Add the following code, which adapts the sample from the main [Android SDK guide](https://developers.enode.com/docs/link-sdks/android) for React Native: ```kotlin package com.your-app-name import android.content.Intent import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.ReactContextBaseJavaModule import com.facebook.react.bridge.ReactMethod import com.facebook.react.bridge.Callback import io.enode.link.LinkKit const val LINK_UI_REQUEST = 99 class LinkUIModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) { private var linkResultCallback: Callback? = null; private val activityEventListener = object : BaseActivityEventListener() { override fun onActivityResult( activity: Activity?, requestCode: Int, resultCode: Int, intent: Intent? ) { if (requestCode == LINK_UI_REQUEST) { if (resultCode == Activity.RESULT_OK) { linkResultCallback?.invoke("success") } else { val errorCode = intent?.getStringExtra(LinkKit.ERROR_CODE) val errorDetails = intent?.getStringExtra(LinkKit.ERROR_DETAILS) linkResultCallback?.invoke(errorCode, errorDetails) } linkResultCallback = null } } } override fun getName() = "LinkUIModule" init { reactContext.addActivityEventListener(activityEventListener) } @ReactMethod fun show(token: String, callback: Callback) { val activity = currentActivity if (activity == null) { callback.invoke("implementationError", "Unable to get current activity") return } try { linkResultCallback = callback val intent = Intent(activity, LinkKit::class.java) intent.putExtra(LinkKit.INTENT_LINK_TOKEN, token); activity.startActivityForResult(intent, LINK_UI_REQUEST, null) } catch (e: RuntimeException) { callback.invoke("implementationError", "RuntimeException whilst launching LinkKit") } } } ``` ### Expose your Kotlin implementation to React Native You need to [register your module](https://reactnative.dev/docs/legacy/native-modules-android?android-language=kotlin#register-the-module-android-specific) as a `ReactPackage` in order to use it in JavaScript. Create a separate Kotlin class under `/android/app/src/main/java/com/your-app-name/LinkUIPackage.kt` and add the following to it: ```kotlin package com.your-app-name import android.view.View import com.facebook.react.ReactPackage import com.facebook.react.bridge.NativeModule import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.uimanager.ReactShadowNode import com.facebook.react.uimanager.ViewManager class LinkUIPackage : ReactPackage { override fun createViewManagers( reactContext: ReactApplicationContext ): MutableList>> = mutableListOf() override fun createNativeModules( reactContext: ReactApplicationContext ): MutableList = listOf(LinkUIModule(reactContext)).toMutableList() } ``` Next, add this package to the list exposed by React. In your project’s `/android/app/src/main/java/com/your-app-name/MainApplication.[kt|java]` file, find where `getPackages()` is implemented and be sure to add the Link UI package to it. It should resemble the following (for more information, see [React Native docs](https://reactnative.dev/docs/native-modules-android?android-language=java#register-the-module-android-specific)): ```java @Override protected List getPackages() { @SuppressWarnings("UnnecessaryLocalVariable") List packages = new PackageList(this).getPackages(); packages.add(new LinkUIPackage()); return packages; } ``` ## Use the SDKs in React Native Now that you have exposed the iOS and Android Link SDKs as native modules, you can use them in React Native. First, [create a link session](https://developers.enode.com/docs/link-sdks/introduction#create-a-link-session) on your server and make sure the resulting `linkToken` is available in your React Native app. (For Android, remember to supply an app deeplink as your redirect URI.) Next, decide where you want to show Link UI and import `NativeModules` there: ```jsx import { NativeModules } from "react-native"; ``` `NativeModules.LinkUIModule` will call native modules you just set up. The following is a complete example of a `LinkUI` React component. If you followed this guide and implemented the same module interface across iOS and Android, the following implementation will be universal across both platforms. ```jsx import { Button, View, NativeModules } from "react-native"; export default function LinkUI({ token }) { const linkUI = NativeModules.LinkUIModule; return (