I have a project on React Native that has a bunch of Native Modules and UI Components. The code is mostly written on Swift but it also has Objective-C code for exporting my swift’s native classes and methods to React Native because Swift doesn’t support C macros, e.g.:
// Calendar.m
#import <React/RCTBridgeModule.h>
@interface RCT_EXTERN_MODULE(Calendar, NSObject)
RCT_EXTERN_METHOD(createEvent:(NSString *)title location:(NSString* )location)
@end
// Calendar.swift
@objc(Calendar)
class Calendar: NSObject {
@objc
func createEvent(_ title: String, location: String) {
print(title, location)
}
}
It’s inconvenient to manage both Objective-C and Swift method interfaces each time of any modification so is there any approach to eliminate Objective-C code?
2
Answers
If you look into React Native macros
RCT_EXTERN_MODULE
,RCT_EXTERN_METHOD
etc. you can find that they produce additional static methods for React Native to register your module and expose your methods:You can implement these methods in your Swift code:
Also you need to register your class manually on app startup to be operable:
Swift Macro
As you can see it's possible to write a React Native Module manually in pure Swift but it is not convenient at all. But macro has been started supporting from Swift 5.9 (XCode 15) and you can use ReactBridge swift macro library for React Native Modules and UI Components. And with this library your code simply becomes to:
If you are open to using expo I have used
Expo Modules API
for native modules before they handle all the nasty objc stuff.They expect you to write your modules in
Kotlin and Swift
but I believe under the hood they are still just generating all the objc code that you need.Expo Modules API
was a great experience especially if you are wanting to write swift code. I wrote a native module without it and felt the objc stuff was hard to keep in sync with the swift code.https://docs.expo.dev/modules/overview/