React Native + SwiftUI Tutorial: How to Embed a SwiftUI Screen in Your React Native App

React Native meets SwiftUI hybrid app development banner

Ever been caught in that in-between zone where you love react native for its cross-platform mobile development superpowers, but wish you could tap into SwiftUI’s native iOS finesse for those trickier moments? Yeah, we’ve been there too.

Imagine your app cruising along just fine using react native app development, but then you hit a screen that needs more. For instance, an AR view, a complex animation, or something that needs to feel deeply native on iOS. And suddenly, you’re thinking, “This would be so much easier in SwiftUI.”

Good news: you don’t have to choose one or the other. In this blog, I’ll walk you through how to embed SwiftUI screens right inside your react native app, smoothly and without a headache.

To make this all a bit more real, I’ll walk through a hands-on react native and SwiftUI tutorial that shows just how these technologies can play together. We’ll build a simple demo app with two connected screens that pass data back and forth in real time. Let’s dive in.

Step 1: Create a New React Native Project

Start by setting up a new React Native project:

npx @react-native-community/cli@latest init RNWithSwiftUICode language: CSS (css)

For teams targeting web and mobile together, react native expo with tamagui integration for web & mobile apps is another practical approach to unify your ui stack.

Step 2: Setup the iOS Native Module

Open the iOS directory in your project in Xcode, and add a new Swift file named NativeBridge.swift

import Foundation
import React
import SwiftUI


@objc(NativeBridge)
class NativeBridge: NSObject {

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

  @objc
  func openSwiftUIScreen(_ data: NSDictionary, callback: @escaping RCTResponseSenderBlock) {
    DispatchQueue.main.async {
      let swiftUIView = SwiftUIView(data: data) { result in
        callback([result])
      }
      let hostingController = UIHostingController(rootView: swiftUIView)
      hostingController.modalPresentationStyle = .fullScreen

      let keyWindow = UIApplication.shared.connectedScenes
        .filter { $0.activationState == .foregroundActive }
        .compactMap { $0 as? UIWindowScene }
        .first?.windows
        .filter { $0.isKeyWindow }
        .first

      if let rootViewController = keyWindow?.rootViewController {
        rootViewController.present(hostingController, animated: true)
      }
    }
  }
}
  • This NativeBridge acts as the main entry point for communication between React Native and native iOS code.

  • The @objc(NativeBridge) annotation makes this Swift class available to Objective-C and React Native.

  • requiresMainQueueSetup method tells React Native that this module needs to be initialized on the main thread.

  • openSwiftUIScreen: This method is invoked from the React Native side.
    First Parameter:
    _ data: NSDictionary: Receives data from React Native.
    Second Parameter:
    callback: @escaping RCTResponseSenderBlock: Sends data back to React Native.

  • Presents the SwiftUIView view modally on the root view controller.

Planning to scale your app globally? See how to start adding multilingual support to your react native app for international readiness.

Why build apps twice when once is enough with cross-platform tools

Step 3: Setup the SwiftUI View

Add a new SwiftUI View file to your iOS project.

import SwiftUI


struct SwiftUIView: View {
  let data: NSDictionary
  let callback: (NSDictionary) -> Void

  @State private var text: String = ""
  @Environment(\.presentationMode) var presentationMode

  var body: some View {
    NavigationStack {
      VStack {
        Text("SwiftUI Screen")
          .font(.title)
          .padding()

        Text("Data from React Native: \(data["message"] as? String ?? "")")
          .padding()

        TextField("Enter text", text: $text)
          .textFieldStyle(RoundedBorderTextFieldStyle())
          .padding()

        Button("Send Data Back") {
          let result: NSDictionary = ["response": text]
          callback(result)
          presentationMode.wrappedValue.dismiss()
        }
        .padding()
      }
      .padding()
      .navigationTitle("SwitftUI")
      .navigationBarTitleDisplayMode(.large)
    }
  }
}Code language: JavaScript (javascript)

The SwiftUI view above takes care of a few key tasks:

  • It displays the data received from React Native

  • Let the user input new information

  • Sends that updated data back to React Native

  • And finally, it handles dismissing itself when done

This approach blends the benefits of hybrid mobile app development with the fluid UI capabilities of SwiftUI and shows the flexibility you get when you hire react native developers who know how to make both ecosystems work together effectively.

Read More: React Native + SwiftUI Tutorial: How to Embed a SwiftUI Screen in Your React Native App

0
Subscribe to my newsletter

Read articles from Mobisoft Infotech directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Mobisoft Infotech
Mobisoft Infotech

Mobisoft Infotech is a software product engineering company dedicated to providing value, quality, and lasting business expansion through digital innovation, change, and the adoption of technology. Our proficiency in digital technology encompasses Mobile, Cloud, DevOps, Web, IoT, AI, UI/UX, Testing, Robotic Process Automation, and various other digital transformation services, catering to companies across a wide range of industries. With more than ten years of experience in constructing digital solutions, offering consulting, and handling outsourcing, Mobisoft has assisted clients from over 30 countries in embracing digital transformation, capitalizing on market prospects, and attaining sustained outcomes.