1 /* 2 * Copyright (c) Meta Platforms, Inc. and affiliates. 3 * 4 * This source code is licensed under the MIT license found in the 5 * LICENSE file in the root directory of this source tree. 6 */ 7 8 #import <Foundation/Foundation.h> 9 #import <UIKit/UIKit.h> 10 11 #import <ABI49_0_0React/ABI49_0_0RCTDefines.h> 12 #import <ABI49_0_0React/ABI49_0_0RCTJSThread.h> 13 14 #import "ABI49_0_0RCTBundleManager.h" 15 16 @class ABI49_0_0RCTBridge; 17 @protocol ABI49_0_0RCTBridgeMethod; 18 @protocol ABI49_0_0RCTTurboModule; 19 @protocol ABI49_0_0RCTTurboModuleRegistry; 20 @class ABI49_0_0RCTModuleRegistry; 21 @class ABI49_0_0RCTViewRegistry; 22 @class ABI49_0_0RCTCallableJSModules; 23 24 /** 25 * The type of a block that is capable of sending a response to a bridged 26 * operation. Use this for returning callback methods to JS. 27 */ 28 typedef void (^ABI49_0_0RCTResponseSenderBlock)(NSArray *response); 29 30 /** 31 * The type of a block that is capable of sending an error response to a 32 * bridged operation. Use this for returning error information to JS. 33 */ 34 typedef void (^ABI49_0_0RCTResponseErrorBlock)(NSError *error); 35 36 /** 37 * Block that bridge modules use to resolve the JS promise waiting for a result. 38 * Nil results are supported and are converted to JS's undefined value. 39 */ 40 typedef void (^ABI49_0_0RCTPromiseResolveBlock)(id result); 41 42 /** 43 * Block that bridge modules use to reject the JS promise waiting for a result. 44 * The error may be nil but it is preferable to pass an NSError object for more 45 * precise error messages. 46 */ 47 typedef void (^ABI49_0_0RCTPromiseRejectBlock)(NSString *code, NSString *message, NSError *error); 48 49 ABI49_0_0RCT_EXTERN_C_BEGIN 50 51 typedef struct ABI49_0_0RCTMethodInfo { 52 const char *const jsName; 53 const char *const objcName; 54 const BOOL isSync; 55 } ABI49_0_0RCTMethodInfo; 56 57 ABI49_0_0RCT_EXTERN_C_END 58 59 /** 60 * Provides the interface needed to register a bridge module. 61 */ 62 @protocol ABI49_0_0RCTBridgeModule <NSObject> 63 64 /** 65 * Place this macro in your class implementation to automatically register 66 * your module with the bridge when it loads. The optional js_name argument 67 * will be used as the JS module name. If omitted, the JS module name will 68 * match the Objective-C class name. 69 */ 70 #define ABI49_0_0RCT_EXPORT_MODULE(js_name) \ 71 ABI49_0_0RCT_EXTERN void ABI49_0_0RCTRegisterModule(Class); \ 72 +(NSString *)moduleName \ 73 { \ 74 return @ #js_name; \ 75 } \ 76 +(void)load \ 77 { \ 78 ABI49_0_0RCTRegisterModule(self); \ 79 } 80 81 /** 82 * Same as ABI49_0_0RCT_EXPORT_MODULE, but uses __attribute__((constructor)) for module 83 * registration. Useful for registering swift classes that forbids use of load 84 * Used in ABI49_0_0RCT_EXTERN_REMAP_MODULE 85 */ 86 #define ABI49_0_0RCT_EXPORT_MODULE_NO_LOAD(js_name, objc_name) \ 87 ABI49_0_0RCT_EXTERN void ABI49_0_0RCTRegisterModule(Class); \ 88 +(NSString *)moduleName \ 89 { \ 90 return @ #js_name; \ 91 } \ 92 __attribute__((constructor)) static void ABI49_0_0RCT_CONCAT(initialize_, objc_name)() \ 93 { \ 94 ABI49_0_0RCTRegisterModule([objc_name class]); \ 95 } 96 97 /** 98 * To improve startup performance users may want to generate their module lists 99 * at build time and hook the delegate to merge with the runtime list. This 100 * macro takes the place of the above for those cases by omitting the +load 101 * generation. 102 * 103 */ 104 #define ABI49_0_0RCT_EXPORT_PRE_REGISTERED_MODULE(js_name) \ 105 +(NSString *)moduleName \ 106 { \ 107 return @ #js_name; \ 108 } 109 110 // Implemented by ABI49_0_0RCT_EXPORT_MODULE 111 + (NSString *)moduleName; 112 113 @optional 114 115 /** 116 * A reference to the ABI49_0_0RCTModuleRegistry. Useful for modules that require access 117 * to other NativeModules. To implement this in your module, just add `@synthesize 118 * moduleRegistry = _moduleRegistry;`. If using Swift, add 119 * `@objc var moduleRegistry: ABI49_0_0RCTModuleRegistry!` to your module. 120 */ 121 @property (nonatomic, weak, readwrite) ABI49_0_0RCTModuleRegistry *moduleRegistry; 122 123 /** 124 * A reference to the ABI49_0_0RCTViewRegistry. Useful for modules that query UIViews, 125 * given a ABI49_0_0React tag. This API is deprecated, and only exists to help migrate 126 * NativeModules to Venice. 127 * 128 * To implement this in your module, just add `@synthesize 129 * viewRegistry_DEPRECATED = _viewRegistry_DEPRECATED;`. If using Swift, add 130 * `@objc var viewRegistry_DEPRECATED: ABI49_0_0RCTViewRegistry!` to your module. 131 */ 132 @property (nonatomic, weak, readwrite) ABI49_0_0RCTViewRegistry *viewRegistry_DEPRECATED; 133 134 /** 135 * A reference to the ABI49_0_0RCTBundleManager. Useful for modules that need to read 136 * or write to the app's bundle URL. 137 * 138 * To implement this in your module, just add `@synthesize bundleManager = 139 * _bundleManager;`. If using Swift, add `@objc var bundleManager: 140 * ABI49_0_0RCTBundleManager!` to your module. 141 */ 142 @property (nonatomic, weak, readwrite) ABI49_0_0RCTBundleManager *bundleManager; 143 144 /** 145 * A reference to an ABI49_0_0RCTCallableJSModules. Useful for modules that need to 146 * call into methods on JavaScript modules registered as callable with 147 * ABI49_0_0React Native. 148 * 149 * To implement this in your module, just add `@synthesize callableJSModules = 150 * _callableJSModules;`. If using Swift, add `@objc var callableJSModules: 151 * ABI49_0_0RCTCallableJSModules!` to your module. 152 */ 153 @property (nonatomic, weak, readwrite) ABI49_0_0RCTCallableJSModules *callableJSModules; 154 155 /** 156 * A reference to the ABI49_0_0RCTBridge. Useful for modules that require access 157 * to bridge features, such as sending events or making JS calls. This 158 * will be set automatically by the bridge when it initializes the module. 159 * To implement this in your module, just add `@synthesize bridge = _bridge;` 160 * If using Swift, add `@objc var bridge: ABI49_0_0RCTBridge!` to your module. 161 */ 162 @property (nonatomic, weak, readonly) ABI49_0_0RCTBridge *bridge; 163 164 /** 165 * The queue that will be used to call all exported methods. If omitted, this 166 * will call on a default background queue, which is avoids blocking the main 167 * thread. 168 * 169 * If the methods in your module need to interact with UIKit methods, they will 170 * probably need to call those on the main thread, as most of UIKit is main- 171 * thread-only. You can tell ABI49_0_0React Native to call your module methods on the 172 * main thread by returning a reference to the main queue, like this: 173 * 174 * - (dispatch_queue_t)methodQueue 175 * { 176 * return dispatch_get_main_queue(); 177 * } 178 * 179 * If you don't want to specify the queue yourself, but you need to use it 180 * inside your class (e.g. if you have internal methods that need to dispatch 181 * onto that queue), you can just add `@synthesize methodQueue = _methodQueue;` 182 * and the bridge will populate the methodQueue property for you automatically 183 * when it initializes the module. 184 */ 185 @property (nonatomic, strong, readonly) dispatch_queue_t methodQueue; 186 187 /** 188 * Wrap the parameter line of your method implementation with this macro to 189 * expose it to JS. By default the exposed method will match the first part of 190 * the Objective-C method selector name (up to the first colon). Use 191 * ABI49_0_0RCT_REMAP_METHOD to specify the JS name of the method. 192 * 193 * For example, in ModuleName.m: 194 * 195 * - (void)doSomething:(NSString *)aString withA:(NSInteger)a andB:(NSInteger)b 196 * { ... } 197 * 198 * becomes 199 * 200 * ABI49_0_0RCT_EXPORT_METHOD(doSomething:(NSString *)aString 201 * withA:(NSInteger)a 202 * andB:(NSInteger)b) 203 * { ... } 204 * 205 * and is exposed to JavaScript as `NativeModules.ModuleName.doSomething`. 206 * 207 * ## Promises 208 * 209 * Bridge modules can also define methods that are exported to JavaScript as 210 * methods that return a Promise, and are compatible with JS async functions. 211 * 212 * Declare the last two parameters of your native method to be a resolver block 213 * and a rejecter block. The resolver block must precede the rejecter block. 214 * 215 * For example: 216 * 217 * ABI49_0_0RCT_EXPORT_METHOD(doSomethingAsync:(NSString *)aString 218 * resolver:(ABI49_0_0RCTPromiseResolveBlock)resolve 219 * rejecter:(ABI49_0_0RCTPromiseRejectBlock)reject 220 * { ... } 221 * 222 * Calling `NativeModules.ModuleName.doSomethingAsync(aString)` from 223 * JavaScript will return a promise that is resolved or rejected when your 224 * native method implementation calls the respective block. 225 * 226 */ 227 #define ABI49_0_0RCT_EXPORT_METHOD(method) ABI49_0_0RCT_REMAP_METHOD(, method) 228 229 /** 230 * Same as ABI49_0_0RCT_EXPORT_METHOD but the method is called from JS 231 * synchronously **on the JS thread**, possibly returning a result. 232 * 233 * WARNING: in the vast majority of cases, you should use ABI49_0_0RCT_EXPORT_METHOD which 234 * allows your native module methods to be called asynchronously: calling 235 * methods synchronously can have strong performance penalties and introduce 236 * threading-related bugs to your native modules. 237 * 238 * The return type must be of object type (id) and should be serializable 239 * to JSON. This means that the hook can only return nil or JSON values 240 * (e.g. NSNumber, NSString, NSArray, NSDictionary). 241 * 242 * Calling these methods when running under the websocket executor 243 * is currently not supported. 244 */ 245 #define ABI49_0_0RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(method) ABI49_0_0RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(id, method) 246 247 #define ABI49_0_0RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(returnType, method) \ 248 ABI49_0_0RCT_REMAP_BLOCKING_SYNCHRONOUS_METHOD(, returnType, method) 249 250 /** 251 * Similar to ABI49_0_0RCT_EXPORT_METHOD but lets you set the JS name of the exported 252 * method. Example usage: 253 * 254 * ABI49_0_0RCT_REMAP_METHOD(executeQueryWithParameters, 255 * executeQuery:(NSString *)query parameters:(NSDictionary *)parameters) 256 * { ... } 257 */ 258 #define ABI49_0_0RCT_REMAP_METHOD(js_name, method) \ 259 _ABI49_0_0RCT_EXTERN_REMAP_METHOD(js_name, method, NO) \ 260 -(void)method ABI49_0_0RCT_DYNAMIC; 261 262 /** 263 * Similar to ABI49_0_0RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD but lets you set 264 * the JS name of the exported method. Example usage: 265 * 266 * ABI49_0_0RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(executeQueryWithParameters, 267 * executeQuery:(NSString *)query parameters:(NSDictionary *)parameters) 268 * { ... } 269 */ 270 #define ABI49_0_0RCT_REMAP_BLOCKING_SYNCHRONOUS_METHOD(js_name, returnType, method) \ 271 _ABI49_0_0RCT_EXTERN_REMAP_METHOD(js_name, method, YES) \ 272 -(returnType)method ABI49_0_0RCT_DYNAMIC; 273 274 /** 275 * Use this macro in a private Objective-C implementation file to automatically 276 * register an external module with the bridge when it loads. This allows you to 277 * register Swift or private Objective-C classes with the bridge. 278 * 279 * For example if one wanted to export a Swift class to the bridge: 280 * 281 * MyModule.swift: 282 * 283 * @objc(MyModule) class MyModule: NSObject { 284 * 285 * @objc func doSomething(string: String! withFoo a: Int, bar b: Int) { ... } 286 * 287 * } 288 * 289 * MyModuleExport.m: 290 * 291 * #import <ABI49_0_0React/ABI49_0_0RCTBridgeModule.h> 292 * 293 * @interface ABI49_0_0RCT_EXTERN_MODULE(MyModule, NSObject) 294 * 295 * ABI49_0_0RCT_EXTERN_METHOD(doSomething:(NSString *)string withFoo:(NSInteger)a bar:(NSInteger)b) 296 * 297 * @end 298 * 299 * This will now expose MyModule and the method to JavaScript via 300 * `NativeModules.MyModule.doSomething` 301 */ 302 #define ABI49_0_0RCT_EXTERN_MODULE(objc_name, objc_supername) ABI49_0_0RCT_EXTERN_REMAP_MODULE(, objc_name, objc_supername) 303 304 /** 305 * Like ABI49_0_0RCT_EXTERN_MODULE, but allows setting a custom JavaScript name. 306 */ 307 #define ABI49_0_0RCT_EXTERN_REMAP_MODULE(js_name, objc_name, objc_supername) \ 308 objc_name: \ 309 objc_supername @ \ 310 end @interface objc_name(ABI49_0_0RCTExternModule)<ABI49_0_0RCTBridgeModule> \ 311 @end \ 312 @implementation objc_name (ABI49_0_0RCTExternModule) \ 313 ABI49_0_0RCT_EXPORT_MODULE_NO_LOAD(js_name, objc_name) 314 315 /** 316 * Use this macro in accordance with ABI49_0_0RCT_EXTERN_MODULE to export methods 317 * of an external module. 318 */ 319 #define ABI49_0_0RCT_EXTERN_METHOD(method) _ABI49_0_0RCT_EXTERN_REMAP_METHOD(, method, NO) 320 321 /** 322 * Use this macro in accordance with ABI49_0_0RCT_EXTERN_MODULE to export methods 323 * of an external module that should be invoked synchronously. 324 */ 325 #define ABI49_0_0RCT_EXTERN__BLOCKING_SYNCHRONOUS_METHOD(method) _ABI49_0_0RCT_EXTERN_REMAP_METHOD(, method, YES) 326 327 /** 328 * Like ABI49_0_0RCT_EXTERN_REMAP_METHOD, but allows setting a custom JavaScript name 329 * and also whether this method is synchronous. 330 */ 331 #define _ABI49_0_0RCT_EXTERN_REMAP_METHOD(js_name, method, is_blocking_synchronous_method) \ 332 +(const ABI49_0_0RCTMethodInfo *)ABI49_0_0RCT_CONCAT(__rct_export__, ABI49_0_0RCT_CONCAT(js_name, ABI49_0_0RCT_CONCAT(__LINE__, __COUNTER__))) \ 333 { \ 334 static ABI49_0_0RCTMethodInfo config = {#js_name, #method, is_blocking_synchronous_method}; \ 335 return &config; \ 336 } 337 338 /** 339 * Most modules can be used from any thread. All of the modules exported non-sync method will be called on its 340 * methodQueue, and the module will be constructed lazily when its first invoked. Some modules have main need to access 341 * information that's main queue only (e.g. most UIKit classes). Since we don't want to dispatch synchronously to the 342 * main thread to this safely, we construct these modules and export their constants ahead-of-time. 343 * 344 * Note that when set to false, the module constructor will be called from any thread. 345 * 346 * This requirement is currently inferred by checking if the module has a custom initializer or if there's exported 347 * constants. In the future, we'll stop automatically inferring this and instead only rely on this method. 348 */ 349 + (BOOL)requiresMainQueueSetup; 350 351 /** 352 * Injects methods into JS. Entries in this array are used in addition to any 353 * methods defined using the macros above. This method is called only once, 354 * before registration. 355 */ 356 - (NSArray<id<ABI49_0_0RCTBridgeMethod>> *)methodsToExport; 357 358 /** 359 * Injects constants into JS. These constants are made accessible via NativeModules.ModuleName.X. It is only called once 360 * for the lifetime of the bridge, so it is not suitable for returning dynamic values, but may be used for long-lived 361 * values such as session keys, that are regenerated only as part of a reload of the entire ABI49_0_0React application. 362 * 363 * If you implement this method and do not implement `requiresMainQueueSetup`, you will trigger deprecated logic 364 * that eagerly initializes your module on bridge startup. In the future, this behaviour will be changed to default 365 * to initializing lazily, and even modules with constants will be initialized lazily. 366 */ 367 - (NSDictionary *)constantsToExport; 368 369 /** 370 * Notifies the module that a batch of JS method invocations has just completed. 371 */ 372 - (void)batchDidComplete; 373 374 /** 375 * Notifies the module that the active batch of JS method invocations has been 376 * partially flushed. 377 * 378 * This occurs before -batchDidComplete, and more frequently. 379 */ 380 - (void)partialBatchDidFlush; 381 382 @end 383 384 /** 385 * A class that allows NativeModules and TurboModules to look up one another. 386 */ 387 @interface ABI49_0_0RCTModuleRegistry : NSObject 388 - (void)setBridge:(ABI49_0_0RCTBridge *)bridge; 389 - (void)setTurboModuleRegistry:(id<ABI49_0_0RCTTurboModuleRegistry>)turboModuleRegistry; 390 391 - (id)moduleForName:(const char *)moduleName; 392 - (id)moduleForName:(const char *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad; 393 @end 394 395 typedef UIView * (^ABI49_0_0RCTBridgelessComponentViewProvider)(NSNumber *); 396 397 typedef void (^ABI49_0_0RCTViewRegistryUIBlock)(ABI49_0_0RCTViewRegistry *viewRegistry); 398 399 /** 400 * A class that allows NativeModules to query for views, given ABI49_0_0React Tags. 401 */ 402 @interface ABI49_0_0RCTViewRegistry : NSObject 403 - (void)setBridge:(ABI49_0_0RCTBridge *)bridge; 404 - (void)setBridgelessComponentViewProvider:(ABI49_0_0RCTBridgelessComponentViewProvider)bridgelessComponentViewProvider; 405 406 - (UIView *)viewForABI49_0_0ReactTag:(NSNumber *)ABI49_0_0ReactTag; 407 - (void)addUIBlock:(ABI49_0_0RCTViewRegistryUIBlock)block; 408 @end 409 410 typedef void (^ABI49_0_0RCTBridgelessJSModuleMethodInvoker)( 411 NSString *moduleName, 412 NSString *methodName, 413 NSArray *args, 414 dispatch_block_t onComplete); 415 416 /** 417 * A class that allows NativeModules to call methods on JavaScript modules registered 418 * as callable with ABI49_0_0React Native. 419 */ 420 @interface ABI49_0_0RCTCallableJSModules : NSObject 421 - (void)setBridge:(ABI49_0_0RCTBridge *)bridge; 422 - (void)setBridgelessJSModuleMethodInvoker:(ABI49_0_0RCTBridgelessJSModuleMethodInvoker)bridgelessJSModuleMethodInvoker; 423 424 - (void)invokeModule:(NSString *)moduleName method:(NSString *)methodName withArgs:(NSArray *)args; 425 - (void)invokeModule:(NSString *)moduleName 426 method:(NSString *)methodName 427 withArgs:(NSArray *)args 428 onComplete:(dispatch_block_t)onComplete; 429 @end 430