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