DEV Community

Cover image for iOS Native Modules in React Native 0.79+: Achieving Two-Way Bridging with the New Architecture🚀
Amit Kumar
Amit Kumar

Posted on

1 1 1 1 1

iOS Native Modules in React Native 0.79+: Achieving Two-Way Bridging with the New Architecture🚀

The New Architecture in React Native 0.79+ brings exciting changes with TurboModules and Fabric! 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: '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

The New Architecture in RN 0.79+ makes 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!

ACI image

ACI.dev: Best Open-Source Composio Alternative (AI Agent Tooling)

100% open-source tool-use platform (backend, dev portal, integration library, SDK/MCP) that connects your AI agents to 600+ tools with multi-tenant auth, granular permissions, and access through direct function calling or a unified MCP server.

Star our GitHub!

Top comments (0)