Spec TypeScript giống ví dụ Kotlin (NativeCalculator.ts).
Bước 1 — Header Obj-C bridging (ios/Calculator/RNCalculator.h):
objc
#import <Foundation/Foundation.h>
#import "RNCalculatorSpec.h" // generated by Codegen
NS_ASSUME_NONNULL_BEGIN
@interface RNCalculator : NSObject <NativeCalculatorSpec>
@end
NS_ASSUME_NONNULL_ENDBước 2 — Implementation Swift (ios/Calculator/RNCalculator.swift):
swift
import Foundation
@objc(RNCalculator)
class RNCalculator: NSObject, NativeCalculatorSpec {
func add(_ a: NSNumber, b: NSNumber) -> NSNumber {
return NSNumber(value: a.doubleValue + b.doubleValue)
}
func fetchUser(_ id: String, resolve: @escaping RCTPromiseResolveBlock,
reject: @escaping RCTPromiseRejectBlock) {
resolve(["name": "Alice"])
}
static func moduleName() -> String { "Calculator" }
}Bước 3 — Bridging header (ios/RNCalculator-Bridging-Header.h):
objc
#import <React/RCTBridgeModule.h>Bước 4 — Module entry Obj-C++ (ios/Calculator/RNCalculator.mm):
objc
#import "RNCalculator.h"
#import "MyApp-Swift.h"
@implementation RNCalculator
RCT_EXPORT_MODULE(Calculator)
@endBước 5 — Calculator.podspec:
ruby
Pod::Spec.new do |s|
s.name = 'Calculator'
s.source_files = "Calculator/**/*.{swift,h,m,mm}"
s.dependency 'React-Core'
install_modules_dependencies(s)
endBước 6 — pod install trong ios/. Codegen chạy → RNCalculatorSpec.h/.mm generate. Build pnpm ios.
Pitfall:
- Swift class phải @objc để Codegen + Obj-C++ thấy.
- Method async dùng RCTPromiseResolveBlock/RCTPromiseRejectBlock.
- Param type: NSNumber cho number, NSString cho string, NSDictionary cho object — Swift Codegen tự bridge.