How to expose swift class to react native class?

By | September 10, 2024

There will be situations where you have to expose your Swift class to React Native. To do this, you need to use some Obj-C Macros available in React Native.

To use these Obj-C Macros, you need a new Obj-C file:

  1. File → New → File… (or CMD+N)
  2. Select Objective-C File
  3. Name your file EligibilityCalculator
//
//  EligibilityCalculator.m
//
//

#import <Foundation/Foundation.h>
#import "React/RCTBridgeModule.h"

@interface RCT_EXTERN_MODULE(EligibilityCalculator, NSObject)
//Your code comes here
@end

You have to import RCTBridgeModule, so that you can use the Macros to bridge the native code.

You’ll use the RCT_EXTERN_MODULE Macro to expose your EligibilityCalculator class to JS:

  1. The first argument is the name of your Swift class
  2. The second is its superclass.

Rename your exposed module (optional)

In case you want to expose your module under a different name, you should use the RCT_EXTERN_REMAP_MODULE Macro instead:

  1. The first argument is the name exposed to JS
  2. The second argument is the Swift class
  3. The third is its superclass

For instance, if you want to expose your module as BMICalculator:

//
//  EligibilityCalculator.m
//
//

#import <Foundation/Foundation.h>
#import "React/RCTBridgeModule.h"

@interface RCT_EXTERN_REMAP_MODULE(BMICalculator, EligibilityCalculator, NSObject)
//Your code comes here
@end

Important: There is another very similar Macro, called RCT_EXPORT_MODULE, but that one is used with Objective-C code. We will use the one with EXTERN.

Access your module from JS

Everything should be set up on the native side. Now let’s move on to the JavaScript side.

In your App.js file, import NativeModules from react-native and let’s see if you can access your EligibilityCalculator module:

// App.js
import { NativeModules } from 'react-native'
console.log(NativeModules.Counter)

Any module exposed to React Native should be available as a property on the NativeModules object.

Apparently, React Native doesn’t expose native classes if you don’t expose some of their methods, as well. So let’s do that.

Create a new swift file and add below code in it.

//
//  EligibilityCalculator.swift
//  UbiMobileApp
//
//

import Foundation


@objc(EligibilityCalculator)
class EligibilityCalculator: UIViewController {
  
  //MARK: Variables
  
  //MARK: ViewDidLoad
  override func viewDidLoad() {
    super.viewDidLoad()
  }
  
//MARK: -Bridge methods
 @objc 
  func calculateEligibilityFor(_ name: String, age: String, height: String, nationality: String) {
    //Add your code here to be executed while getting called from RN class.
  }
}

Important: we need to use the @objc directive on each method / property that needs to be called or accessed from Obj-C

Next you have to expose the method to React Native’s bridge, from your Obj-C file, using the RCT_EXTERN_METHOD Macro and passing the method name:

//
// EligibilityCalculator.m
//
//

#import <Foundation/Foundation.h>
#import "React/RCTBridgeModule.h"

@interface RCT_EXTERN_MODULE(EligibilityCalculator, NSObject)

// Bridging module

RCT_EXTERN_METHOD(calculateEligibilityFor:(NSString *)name age:(NSString *)age height:(NSString *)height nationality:(NSString *)nationality)

@end

Now, if you call your Swift method from JS, it should execute methods in your swift class. Use this method to learn how to pass multiple parameters from react native method to native swift methods.

Leave a Reply

Your email address will not be published. Required fields are marked *