This content originally appeared on DEV Community and was authored by Ajmal Hasan
React Native’s new architecture introduces Turbo Modules, which significantly improve native module communication with JavaScript. This guide will walk you through creating a Swift-based Turbo Module for iOS, ensuring smooth interaction with React Native.
What is a Turbo Module?
A Turbo Module is an advanced native module that offers:
Faster execution: Direct invocation via JSC/Hermes.
Automatic TypeScript/Flow integration: Generates native code automatically.
Efficient memory management: Modules are loaded only when needed.
Prerequisites: Basic React Native knowledge is required. No prior Swift or Objective-C experience is necessary.
Official Documentation
Before diving in, you can explore the official Turbo Modules documentation, which provides comprehensive coverage of Android, Objective-C, JavaScript/TypeScript, and specifications. In this guide, we’ll focus specifically on the iOS Swift implementation to streamline your learning process:
React Native Turbo Modules Introduction
For more insights into the old/new native bridging architecture, explore these articles:
Android Native Bridging in React Native – Part 1
iOS Native Bridging in React Native – Part 2
Build-native-and-turbo-modules
Project Structure
We will create a NativeLocalStorage Turbo Module using Swift.
NativeLocalStorage/
βββ RCTNativeLocalStorage.h
βββ RCTNativeLocalStorage.mm
βββ RCTNativeLocalStorageSwift.swift
βββ RN_NewArch-Bridging-Header.h
How to Create These Files in Xcode?
1) Create a New Group (Optional but Recommended)
To keep your project organized, you can create a new group in Xcode:
- Right-click on the project navigator (left panel in Xcode).
- Select New Group.
- Name it NativeLocalStorage (or any preferred name).
- Move all related files into this group.
2) Create a New File
- Right-click on the
NativeLocalStorage
folder (group) in Xcode. - Select New File from Template.
3) Bridging Header (RN_NewArch-Bridging-Header.h
)
- When you create a new Swift file in an Objective-C project, Xcode will automatically prompt you to create a bridging header(Only One is Needed).
-
If it is not created automatically, follow these steps:
- Select Header File (.h) from the template list.
- Name it
<ProjectName>-Bridging-Header.h
. - Navigate to Build Settings β Swift Compiler – General.
- Set Objective-C Bridging Header to:
$(SRCROOT)/<ProjectName>/<ProjectName>-Bridging-Header.h
4) Objective-C Interface (RCTNativeLocalStorage.h
)
- Select Objective-C File (.h) from the template list.
- Name it
RCTNativeLocalStorage.h
.
5) Swift Implementation (RCTNativeLocalStorageSwift.swift
)
- Select Swift File (.swift) from the template list.
- Name it
RCTNativeLocalStorageSwift.swift
.
6) Objective-C Implementation (RCTNativeLocalStorage.mm
)
- Select Objective-C File (.mm) from the template list.
- Name it
RCTNativeLocalStorage.mm
.
1⃣ Bridging Header (RN_NewArch-Bridging-Header.h
)
Code Explanation:
// RN_NewArch-Bridging-Header.h
#import "RCTAppDelegate.h"
- This bridging header allows Swift code to interact with Objective-C components in React Native.
- The
#import "RCTAppDelegate.h"
ensures compatibility with the React Native app delegate.
2⃣ Objective-C Interface (RCTNativeLocalStorage.h
)
Code Explanation:
#import <Foundation/Foundation.h>
#import <NativeLocalStorageSpec/NativeLocalStorageSpec.h>
@interface RCTNativeLocalStorage : NSObject <NativeLocalStorageSpec>
@end
-
@interface RCTNativeLocalStorage
: Declares the native module class. -
<NativeLocalStorageSpec>
: Ensures the class conforms to the required React Native module interface. -
@end
: Marks the end of the class declaration.
3⃣ Swift Implementation (RCTNativeLocalStorageSwift.swift
)
Code Explanation:
import Foundation
@objcMembers
class RCTNativeLocalStorageImpl: NSObject {
private let userDefaults: UserDefaults
override init() {
userDefaults = UserDefaults(suiteName: "local-storage") ?? UserDefaults.standard
super.init()
}
func getItem(_ key: String) -> String? {
return userDefaults.string(forKey: key)
}
func setItem(_ value: String, forKey key: String) {
userDefaults.set(value, forKey: key)
}
func removeItem(_ key: String) {
userDefaults.removeObject(forKey: key)
}
func clear() {
for (key, _) in userDefaults.dictionaryRepresentation() {
userDefaults.removeObject(forKey: key)
}
}
}
-
@objcMembers
: Ensures all methods are accessible in Objective-C. -
UserDefaults
: Provides persistent storage for key-value pairs. -
CRUD Operations:
-
getItem
: Fetches a stored value. -
setItem
: Stores a value. -
removeItem
: Deletes a specific item. -
clear
: Removes all stored items.
-
4⃣ Objective-C Implementation (RCTNativeLocalStorage.mm
)
Code Explanation:
#import "RCTNativeLocalStorage.h"
#import "RN_NewArch-Swift.h"
@implementation RCTNativeLocalStorage
RCT_EXPORT_MODULE("NativeLocalStorage");
RCTNativeLocalStorageImpl *nativeLocalStorage = [[RCTNativeLocalStorageImpl alloc] init];
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params {
return std::make_shared<facebook::react::NativeLocalStorageSpecJSI>(params);
}
- (NSString *_Nullable)getItem:(nonnull NSString *)key {
return [nativeLocalStorage getItem:key];
}
- (void)setItem:(nonnull NSString *)value key:(nonnull NSString *)key {
[nativeLocalStorage setItem:value forKey:key];
}
-
RCT_EXPORT_MODULE("NativeLocalStorage")
: Registers the module with React Native. -
RCTNativeLocalStorageImpl
: Calls the Swift implementation. -
TurboModule Integration:
- Uses
std::shared_ptr
to efficiently manage memory.
- Uses
Bridges Swift functions to Objective-C, allowing React Native to interact with them.
Summary
Turbo Modules enhance React Nativeβs performance by enabling direct communication.\
We built a Swift-based Turbo Module for local storage.\
Objective-C wrappers ensured React Native compatibility.\
This setup allows Swift-based Turbo Modules to be used in React Native projects seamlessly.
Now you can build custom Turbo Modules in Swift!
This content originally appeared on DEV Community and was authored by Ajmal Hasan