DEV Community

Cover image for iOS Native Modules in React Native: Achieving Two-Way Bridging🚀
Amit Kumar
Amit Kumar

Posted on • Edited on

1 1 1 1 1

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) 💻



📄 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.



📄 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: 'amit@gmail.com', 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!

Vaadin – an open-source web app framework.

Vaadin – an open-source web app framework.

One language. Full-stack web apps. With Vaadin, you build secure, modern web apps — end to end — 100% in Java.

Learn More

Top comments (0)

Sonar image

Explore the coding personalities of leading LLMs

Sonar’s new report on leading LLMs explores the critical tradeoffs between performance and security. Explore the distinct coding personalities of models like OpenAI’s GPT-4o and Claude Sonnet 4 to determine the best AI strategy for your team.

Read now