DEV Community

Cover image for iOS Native Modules in React Native: Achieving Two-Way Bridging๐Ÿš€
Amit Kumar
Amit Kumar

Posted on • Edited on

iOS Native Modules in React Native: Achieving Two-Way Bridging๐Ÿš€

Let's dive deep into creating powerful native modules that bridge JavaScript and iOS seamlessly. โœจ

๐Ÿ› ๏ธ Step-by-Step: Create a Native Module in Swift

Letโ€™s build a simple module called MyNativeModule that:

  • Sends data from JS to iOS ๐Ÿ“ค
  • Sends events from iOS to JS ๐Ÿ“ฉ

1๏ธโƒฃ Create MyNativeModule.swift (Swift) ๐Ÿ’ป


Image description


๐Ÿ“„ File: MyNativeModule.swift

import Foundation
import React

@objc(MyNativeModule)
class MyNativeModule: RCTEventEmitter {

  // MARK: - JS โ†’ iOS
  @objc
  func receivedData(_ params: NSDictionary, callback: RCTResponseSenderBlock) {
    print("๐Ÿ“ฆ Received from JS:", params)
    // callback(["โœ… iOS received your data!"])
  }

  // MARK: - iOS โ†’ JS
  @objc
  func triggerMessageToRN() {
    let eventData: [String: Any] = ["message": "๐Ÿ‘‹ Hello from iOS! ๐ŸŽ‰"]
    sendEvent(withName: "onMessageFromNative", body: eventData)
  }

  // MARK: - Required Overrides
  override func supportedEvents() -> [String] {
    return ["onMessageFromNative"]
  }

  override static func requiresMainQueueSetup() -> Bool {
    return true
  }
}

Enter fullscreen mode Exit fullscreen mode

๐Ÿ“ This class extends RCTEventEmitter to support two-way communication.


2๏ธโƒฃ Create Objective-C Bridge (MyNativeModule.m) ๐Ÿ”Œ

Even though youโ€™re using Swift, React Native still requires an Objective-C header to expose the module to JS.


Image description


๐Ÿ“„ File: MyNativeModule.m

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

@interface RCT_EXTERN_MODULE(MyNativeModule, NSObject)

RCT_EXTERN_METHOD(receivedData:(NSDictionary *)params callback:(RCTResponseSenderBlock)callback)
RCT_EXTERN_METHOD(triggerMessageToRN:(NSDictionary *)params callback:(RCTResponseSenderBlock)callback)
@end

Enter fullscreen mode Exit fullscreen mode

๐Ÿ”— This bridges Swift methods to the RN JS runtime.


๐Ÿง  Using the Native Module in JS (React Native Side)

Letโ€™s test our newly created native module in a sample React Native app:

๐Ÿ“„ File: App.js

import React, {useEffect} from 'react';
import {
  StyleSheet,
  View,
  Text,
  Button,
  NativeModules,
  NativeEventEmitter,
} from 'react-native';

const {MyNativeModule} = NativeModules;
const eventEmitter = new NativeEventEmitter(MyNativeModule);

const App = () => {
  useEffect(() => {
    const subscription = eventEmitter.addListener(
      'onMessageFromNative',
      data => {
        console.log('๐Ÿ“จ Message from iOS:', data.message);
      }
    );

    return () => subscription.remove();
  }, []);

  const sendDataToiOS = () => {
    MyNativeModule.receivedData(
      { userName: '[email protected]', age: '29' },
      response => console.log('โœ… Callback from iOS:', response)
    );
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>๐Ÿš€ React Native + Swift Bridge</Text>
      <Button title="๐Ÿ“ค Send Data to iOS" onPress={sendDataToiOS} />
      <Button
        title="๐Ÿ“จ Receive Event from iOS"
        onPress={() => MyNativeModule.triggerMessageToRN()}
      />
    </View>
  );
};

export default App;

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
  },
  title: {
    fontSize: 20,
    marginBottom: 20,
    fontWeight: 'bold',
  },
});

Enter fullscreen mode Exit fullscreen mode

โœ… Results

๐Ÿงช Try it out:

  • Tap Send Data to iOS โ†’ Check Xcode logs for received data.
  • Tap Trigger iOS to JS โ†’ Watch for JS console logs like ๐Ÿ“จ Message from iOS: Hello from iOS! ๐ŸŽ‰.

โš™๏ธ Troubleshooting Tips

โœ… Clean your build folder (Cmd + Shift + K)
โœ… Make sure RCT_EXTERN_MODULE is present
โœ… Check that Swift is correctly initialized in your project
โœ… Use use_frameworks! in your Podfile for Swift support


๐Ÿ Final Thoughts

It easier and faster to bridge native code with JavaScript. With TurboModules, native communication is now more optimized and type-safe.

๐Ÿ’ก Whether youโ€™re building a native camera module, voice recognition, or secure authentication โ€” the same pattern applies.


๐Ÿ’ฌ Drop a Comment
Was this guide helpful? Stuck somewhere?
Drop a comment below๐Ÿ‘‡

๐Ÿ” Donโ€™t forget to like and share to help others in the RN community!

Top comments (0)