DEV Community

Cover image for Implementing Native Code in React Native
Paulo Messias
Paulo Messias

Posted on

Implementing Native Code in React Native

Hey devs!

React Native is an excellent tool for building mobile applications with a single codebase that can run on both iOS and Android. However, sometimes we need to access platform-specific functionalities that are not available in the standard React Native library. In these situations, we can turn to native code implementations.

In this post, we will explore how to add native functionalities to your React Native application using native packages. We will use the example of a Gallery library, which already has native implementations in Swift for iOS and Kotlin for Android.

Why Use Native Code?

  • Performance: Native code can be optimized for the specific platform, offering better performance.
  • Access to Specific APIs: Some functionalities are only available through native APIs.
  • Integration with Native Libraries: Use of libraries or SDKs that only exist in native form.

Setting Up the Environment

Before we start, make sure you have your environment set up for React Native development, including Xcode for iOS and Android Studio for Android.

Project Structure

Assume we have the following basic structure of a React Native project:

my-react-native-app
├── android
├── ios
├── src
│   ├── components
│   ├── screens
│   ├── App.js
├── package.json
Enter fullscreen mode Exit fullscreen mode

Adding Native Code

Creating the Native Module

Let's create a native module that exposes gallery functionalities. We'll start with Android using Kotlin.

Android (Kotlin)

1- Create a new Kotlin module:
Navigate to android/app/src/main/java/com/myreactnativeapp/ and create a new directory gallery.

2- Add the Kotlin class:
Create a GalleryModule.kt file inside the gallery directory:

   package com.myreactnativeapp.gallery

   import com.facebook.react.bridge.ReactApplicationContext
   import com.facebook.react.bridge.ReactContextBaseJavaModule
   import com.facebook.react.bridge.ReactMethod
   import com.facebook.react.bridge.Promise

   class GalleryModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {

       override fun getName(): String {
           return "GalleryModule"
       }

       @ReactMethod
       fun openGallery(promise: Promise) {
           // Implementation to open the gallery
           promise.resolve("Gallery opened successfully!")
       }
   }
Enter fullscreen mode Exit fullscreen mode

3- Register the module:
In the same directory, create a GalleryPackage.kt file:

   package com.myreactnativeapp.gallery

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

   class GalleryPackage : ReactPackage {
       override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
           return listOf(GalleryModule(reactContext))
       }

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

4- Update MainApplication.java:
Add the new package to the list of registered packages:

   import com.myreactnativeapp.gallery.GalleryPackage;  // Import the package

   @Override
   protected List<ReactPackage> getPackages() {
       @SuppressWarnings("UnnecessaryLocalVariable")
       List<ReactPackage> packages = new PackageList(this).getPackages();
       packages.add(new GalleryPackage());  // Add the new package
       return packages;
   }
Enter fullscreen mode Exit fullscreen mode

iOS (Swift)

1- Create the Swift module:
Navigate to ios and open the project in Xcode. In ios, create a new Swift file GalleryModule.swift inside the Libraries directory.

   import Foundation
   import React

   @objc(GalleryModule)
   class GalleryModule: NSObject {

       @objc
       func openGallery(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
           // Implementation to open the gallery
           resolve("Gallery opened successfully!")
       }
   }
Enter fullscreen mode Exit fullscreen mode

2- Update the bridge header:
Open ios/YourProjectName-Bridging-Header.h and add:

   #import "React/RCTBridgeModule.h"
Enter fullscreen mode Exit fullscreen mode

3- Register the module:
Open AppDelegate.m and add the module registration:

   #import <React/RCTBridge.h>
   #import <React/RCTBridgeModule.h>

   @implementation AppDelegate

   - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
   {
     RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
     [bridge registerModuleForName:@"GalleryModule" withClass:[GalleryModule class]];
     // Rest of the code
   }
Enter fullscreen mode Exit fullscreen mode

Using the Native Module in React Native

Now that we have our native modules set up, we can use them in our JavaScript code.

1- Create a JavaScript file for the module:

   // src/nativeModules/GalleryModule.js
   import { NativeModules } from 'react-native';
   const { GalleryModule } = NativeModules;

   const openGallery = async () => {
     try {
       const result = await GalleryModule.openGallery();
       console.log(result);
     } catch (error) {
       console.error(error);
     }
   };

   export { openGallery };
Enter fullscreen mode Exit fullscreen mode

2- Use the module in your component:

   // src/screens/GalleryScreen.js
   import React from 'react';
   import { View, Button } from 'react-native';
   import { openGallery } from '../nativeModules/GalleryModule';

   const GalleryScreen = () => {
     return (
       <View>
         <Button title="Open Gallery" onPress={openGallery} />
       </View>
     );
   };

   export default GalleryScreen;
Enter fullscreen mode Exit fullscreen mode

Conclusion

Adding native code to your React Native application can seem challenging at first, but with the right steps, you can easily extend your app's capabilities to include platform-specific functionalities. This guide has shown how to create and integrate simple native modules for both Android and iOS. With this foundation, you can explore further and add complex functionalities as needed.

References

  1. React Native Documentation on Native Modules
  2. React Native Documentation on Integrating with Swift
  3. React Native Documentation on Integrating with Kotlin

This guide should provide a solid foundation for you to start working with native code in React Native. If you have any questions or run into issues, the React Native community is very active and can be an excellent resource for additional support.

Top comments (0)