2015-03-23 20:28:42 +00:00
|
|
|
/**
|
|
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
|
|
*/
|
2015-02-20 04:10:52 +00:00
|
|
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
|
2016-11-23 15:47:52 +00:00
|
|
|
#import <React/RCTDefines.h>
|
2015-06-10 10:43:55 +00:00
|
|
|
|
2015-02-20 04:10:52 +00:00
|
|
|
@class RCTBridge;
|
2015-11-03 22:45:46 +00:00
|
|
|
@protocol RCTBridgeMethod;
|
2015-02-20 04:10:52 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The type of a block that is capable of sending a response to a bridged
|
|
|
|
* operation. Use this for returning callback methods to JS.
|
|
|
|
*/
|
|
|
|
typedef void (^RCTResponseSenderBlock)(NSArray *response);
|
|
|
|
|
2015-07-07 15:47:23 +00:00
|
|
|
/**
|
|
|
|
* The type of a block that is capable of sending an error response to a
|
|
|
|
* bridged operation. Use this for returning error information to JS.
|
|
|
|
*/
|
|
|
|
typedef void (^RCTResponseErrorBlock)(NSError *error);
|
|
|
|
|
2015-06-09 21:26:40 +00:00
|
|
|
/**
|
|
|
|
* Block that bridge modules use to resolve the JS promise waiting for a result.
|
|
|
|
* Nil results are supported and are converted to JS's undefined value.
|
|
|
|
*/
|
|
|
|
typedef void (^RCTPromiseResolveBlock)(id result);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Block that bridge modules use to reject the JS promise waiting for a result.
|
|
|
|
* The error may be nil but it is preferable to pass an NSError object for more
|
|
|
|
* precise error messages.
|
|
|
|
*/
|
2016-01-19 20:19:47 +00:00
|
|
|
typedef void (^RCTPromiseRejectBlock)(NSString *code, NSString *message, NSError *error);
|
2015-06-09 21:26:40 +00:00
|
|
|
|
2015-04-26 02:18:39 +00:00
|
|
|
/**
|
|
|
|
* This constant can be returned from +methodQueue to force module
|
|
|
|
* methods to be called on the JavaScript thread. This can have serious
|
|
|
|
* implications for performance, so only use this if you're sure it's what
|
|
|
|
* you need.
|
|
|
|
*
|
|
|
|
* NOTE: RCTJSThread is not a real libdispatch queue
|
|
|
|
*/
|
2015-06-19 11:18:54 +00:00
|
|
|
extern dispatch_queue_t RCTJSThread;
|
2015-04-26 02:18:39 +00:00
|
|
|
|
2015-02-20 04:10:52 +00:00
|
|
|
/**
|
2015-02-24 17:06:57 +00:00
|
|
|
* Provides the interface needed to register a bridge module.
|
2015-02-20 04:10:52 +00:00
|
|
|
*/
|
2015-04-08 12:42:43 +00:00
|
|
|
@protocol RCTBridgeModule <NSObject>
|
2015-08-25 11:27:09 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Place this macro in your class implementation to automatically register
|
|
|
|
* your module with the bridge when it loads. The optional js_name argument
|
|
|
|
* will be used as the JS module name. If omitted, the JS module name will
|
|
|
|
* match the Objective-C class name.
|
|
|
|
*/
|
|
|
|
#define RCT_EXPORT_MODULE(js_name) \
|
|
|
|
RCT_EXTERN void RCTRegisterModule(Class); \
|
|
|
|
+ (NSString *)moduleName { return @#js_name; } \
|
|
|
|
+ (void)load { RCTRegisterModule(self); }
|
|
|
|
|
|
|
|
// Implemented by RCT_EXPORT_MODULE
|
|
|
|
+ (NSString *)moduleName;
|
|
|
|
|
2015-02-20 04:10:52 +00:00
|
|
|
@optional
|
|
|
|
|
|
|
|
/**
|
2015-03-01 23:33:55 +00:00
|
|
|
* A reference to the RCTBridge. Useful for modules that require access
|
|
|
|
* to bridge features, such as sending events or making JS calls. This
|
|
|
|
* will be set automatically by the bridge when it initializes the module.
|
2015-06-19 11:18:54 +00:00
|
|
|
* To implement this in your module, just add `@synthesize bridge = _bridge;`
|
2015-02-20 04:10:52 +00:00
|
|
|
*/
|
2015-11-25 11:09:00 +00:00
|
|
|
@property (nonatomic, weak, readonly) RCTBridge *bridge;
|
2015-02-20 04:10:52 +00:00
|
|
|
|
2015-06-19 11:18:54 +00:00
|
|
|
/**
|
|
|
|
* The queue that will be used to call all exported methods. If omitted, this
|
|
|
|
* will call on a default background queue, which is avoids blocking the main
|
|
|
|
* thread.
|
|
|
|
*
|
|
|
|
* If the methods in your module need to interact with UIKit methods, they will
|
|
|
|
* probably need to call those on the main thread, as most of UIKit is main-
|
|
|
|
* thread-only. You can tell React Native to call your module methods on the
|
|
|
|
* main thread by returning a reference to the main queue, like this:
|
|
|
|
*
|
|
|
|
* - (dispatch_queue_t)methodQueue
|
|
|
|
* {
|
|
|
|
* return dispatch_get_main_queue();
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* If you don't want to specify the queue yourself, but you need to use it
|
2016-01-04 14:23:51 +00:00
|
|
|
* inside your class (e.g. if you have internal methods that need to dispatch
|
2015-06-19 11:18:54 +00:00
|
|
|
* onto that queue), you can just add `@synthesize methodQueue = _methodQueue;`
|
|
|
|
* and the bridge will populate the methodQueue property for you automatically
|
|
|
|
* when it initializes the module.
|
|
|
|
*/
|
[ReactNative] Move module info from bridge to RCTModuleData
Summary:
@public
The info about bridge modules (such as id, name, queue, methods...) was spread
across arrays & dictionaries on the bridge, move it into a specific class.
It also removes a lot of information that was statically cached, and now have
the same lifecycle of the bridge.
Also moved RCTModuleMethod, RCTFrameUpdate and RCTBatchedBridge into it's own
files, for organization sake.
NOTE: This diff seems huge, but most of it was just moving code :)
Test Plan:
Tested UIExplorer & UIExplorer tests, Catalyst, MAdMan and Groups. Everything
looks fine.
2015-06-24 23:34:56 +00:00
|
|
|
@property (nonatomic, strong, readonly) dispatch_queue_t methodQueue;
|
2015-06-19 11:18:54 +00:00
|
|
|
|
2015-04-08 15:52:48 +00:00
|
|
|
/**
|
|
|
|
* Wrap the parameter line of your method implementation with this macro to
|
[Bridge] `RCT_REMAP_METHOD(js_name, selector)`
Summary:
cc @a2 @nicklockwood
This diff introduces a new macro called `RCT_EXPORT_NAMED_METHOD`, which is like `RCT_EXPORT_METHOD` but lets you choose the name of the method in JS. This diff is backwards compatible with the `RCT_EXPORT_METHOD` and legacy `RCT_EXPORT` macros.
The entries in the data segment now contain `__func__`, the Obj-C selector signature, and the JS name. If the JS name is `NULL`, we take the legacy `RCT_EXPORT` code path. If the JS name is an empty string, we use the Obj-C selector's name up to the first colon (that is, the behavior of `RCT_EXPORT_METHOD`).
Since there are three values in each data segment entry, the macros now specify 1-byte alignment. Without the byte alignment, the compiler defaults to 2-byte alignment meaning that each entry takes up 4 bytes instead of 3. The extra byte isn't a concern but being explicit about the alignment should reduce compiler surprises.
Closes https://github.com/facebook/react-native/pull/802
Github Author: James Ide <ide@jameside.com>
Test Plan: Imported from GitHub, without a `Test Plan:` line.
2015-04-14 20:03:16 +00:00
|
|
|
* expose it to JS. By default the exposed method will match the first part of
|
|
|
|
* the Objective-C method selector name (up to the first colon). Use
|
|
|
|
* RCT_REMAP_METHOD to specify the JS name of the method.
|
2015-04-08 15:52:48 +00:00
|
|
|
*
|
2015-04-11 22:08:00 +00:00
|
|
|
* For example, in ModuleName.m:
|
2015-04-08 15:52:48 +00:00
|
|
|
*
|
|
|
|
* - (void)doSomething:(NSString *)aString withA:(NSInteger)a andB:(NSInteger)b
|
2015-04-11 22:08:00 +00:00
|
|
|
* { ... }
|
2015-04-08 15:52:48 +00:00
|
|
|
*
|
|
|
|
* becomes
|
|
|
|
*
|
|
|
|
* RCT_EXPORT_METHOD(doSomething:(NSString *)aString
|
|
|
|
* withA:(NSInteger)a
|
|
|
|
* andB:(NSInteger)b)
|
2015-04-11 22:08:00 +00:00
|
|
|
* { ... }
|
2015-04-08 15:52:48 +00:00
|
|
|
*
|
|
|
|
* and is exposed to JavaScript as `NativeModules.ModuleName.doSomething`.
|
2015-06-09 21:26:40 +00:00
|
|
|
*
|
|
|
|
* ## Promises
|
|
|
|
*
|
|
|
|
* Bridge modules can also define methods that are exported to JavaScript as
|
|
|
|
* methods that return a Promise, and are compatible with JS async functions.
|
|
|
|
*
|
|
|
|
* Declare the last two parameters of your native method to be a resolver block
|
|
|
|
* and a rejecter block. The resolver block must precede the rejecter block.
|
|
|
|
*
|
|
|
|
* For example:
|
|
|
|
*
|
|
|
|
* RCT_EXPORT_METHOD(doSomethingAsync:(NSString *)aString
|
|
|
|
* resolver:(RCTPromiseResolveBlock)resolve
|
|
|
|
* rejecter:(RCTPromiseRejectBlock)reject
|
|
|
|
* { ... }
|
|
|
|
*
|
|
|
|
* Calling `NativeModules.ModuleName.doSomethingAsync(aString)` from
|
|
|
|
* JavaScript will return a promise that is resolved or rejected when your
|
|
|
|
* native method implementation calls the respective block.
|
|
|
|
*
|
2015-04-08 15:52:48 +00:00
|
|
|
*/
|
|
|
|
#define RCT_EXPORT_METHOD(method) \
|
[Bridge] `RCT_REMAP_METHOD(js_name, selector)`
Summary:
cc @a2 @nicklockwood
This diff introduces a new macro called `RCT_EXPORT_NAMED_METHOD`, which is like `RCT_EXPORT_METHOD` but lets you choose the name of the method in JS. This diff is backwards compatible with the `RCT_EXPORT_METHOD` and legacy `RCT_EXPORT` macros.
The entries in the data segment now contain `__func__`, the Obj-C selector signature, and the JS name. If the JS name is `NULL`, we take the legacy `RCT_EXPORT` code path. If the JS name is an empty string, we use the Obj-C selector's name up to the first colon (that is, the behavior of `RCT_EXPORT_METHOD`).
Since there are three values in each data segment entry, the macros now specify 1-byte alignment. Without the byte alignment, the compiler defaults to 2-byte alignment meaning that each entry takes up 4 bytes instead of 3. The extra byte isn't a concern but being explicit about the alignment should reduce compiler surprises.
Closes https://github.com/facebook/react-native/pull/802
Github Author: James Ide <ide@jameside.com>
Test Plan: Imported from GitHub, without a `Test Plan:` line.
2015-04-14 20:03:16 +00:00
|
|
|
RCT_REMAP_METHOD(, method)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Similar to RCT_EXPORT_METHOD but lets you set the JS name of the exported
|
|
|
|
* method. Example usage:
|
|
|
|
*
|
|
|
|
* RCT_REMAP_METHOD(executeQueryWithParameters,
|
|
|
|
* executeQuery:(NSString *)query parameters:(NSDictionary *)parameters)
|
|
|
|
* { ... }
|
|
|
|
*/
|
|
|
|
#define RCT_REMAP_METHOD(js_name, method) \
|
2015-04-23 16:28:09 +00:00
|
|
|
RCT_EXTERN_REMAP_METHOD(js_name, method) \
|
|
|
|
- (void)method
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Use this macro in a private Objective-C implementation file to automatically
|
|
|
|
* register an external module with the bridge when it loads. This allows you to
|
|
|
|
* register Swift or private Objective-C classes with the bridge.
|
|
|
|
*
|
|
|
|
* For example if one wanted to export a Swift class to the bridge:
|
|
|
|
*
|
|
|
|
* MyModule.swift:
|
|
|
|
*
|
|
|
|
* @objc(MyModule) class MyModule: NSObject {
|
|
|
|
*
|
|
|
|
* @objc func doSomething(string: String! withFoo a: Int, bar b: Int) { ... }
|
|
|
|
*
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* MyModuleExport.m:
|
|
|
|
*
|
2016-11-23 15:47:52 +00:00
|
|
|
* #import <React/RCTBridgeModule.h>
|
2015-04-23 16:28:09 +00:00
|
|
|
*
|
|
|
|
* @interface RCT_EXTERN_MODULE(MyModule, NSObject)
|
|
|
|
*
|
|
|
|
* RCT_EXTERN_METHOD(doSomething:(NSString *)string withFoo:(NSInteger)a bar:(NSInteger)b)
|
|
|
|
*
|
|
|
|
* @end
|
|
|
|
*
|
|
|
|
* This will now expose MyModule and the method to JavaScript via
|
|
|
|
* `NativeModules.MyModule.doSomething`
|
|
|
|
*/
|
|
|
|
#define RCT_EXTERN_MODULE(objc_name, objc_supername) \
|
|
|
|
RCT_EXTERN_REMAP_MODULE(, objc_name, objc_supername)
|
|
|
|
|
|
|
|
/**
|
2015-06-09 21:26:40 +00:00
|
|
|
* Like RCT_EXTERN_MODULE, but allows setting a custom JavaScript name.
|
2015-04-23 16:28:09 +00:00
|
|
|
*/
|
|
|
|
#define RCT_EXTERN_REMAP_MODULE(js_name, objc_name, objc_supername) \
|
|
|
|
objc_name : objc_supername \
|
|
|
|
@end \
|
|
|
|
@interface objc_name (RCTExternModule) <RCTBridgeModule> \
|
|
|
|
@end \
|
|
|
|
@implementation objc_name (RCTExternModule) \
|
|
|
|
RCT_EXPORT_MODULE(js_name)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Use this macro in accordance with RCT_EXTERN_MODULE to export methods
|
|
|
|
* of an external module.
|
|
|
|
*/
|
|
|
|
#define RCT_EXTERN_METHOD(method) \
|
|
|
|
RCT_EXTERN_REMAP_METHOD(, method)
|
|
|
|
|
|
|
|
/**
|
2015-06-09 21:26:40 +00:00
|
|
|
* Like RCT_EXTERN_REMAP_METHOD, but allows setting a custom JavaScript name.
|
2015-04-23 16:28:09 +00:00
|
|
|
*/
|
|
|
|
#define RCT_EXTERN_REMAP_METHOD(js_name, method) \
|
2015-11-03 22:45:46 +00:00
|
|
|
+ (NSArray<NSString *> *)RCT_CONCAT(__rct_export__, \
|
|
|
|
RCT_CONCAT(js_name, RCT_CONCAT(__LINE__, __COUNTER__))) { \
|
2015-06-10 10:43:55 +00:00
|
|
|
return @[@#js_name, @#method]; \
|
2015-09-18 22:01:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Injects methods into JS. Entries in this array are used in addition to any
|
|
|
|
* methods defined using the macros above. This method is called only once,
|
|
|
|
* before registration.
|
|
|
|
*/
|
2015-11-03 22:45:46 +00:00
|
|
|
- (NSArray<id<RCTBridgeMethod>> *)methodsToExport;
|
2015-06-10 10:43:55 +00:00
|
|
|
|
2015-02-20 04:10:52 +00:00
|
|
|
/**
|
|
|
|
* Injects constants into JS. These constants are made accessible via
|
2015-09-18 22:01:21 +00:00
|
|
|
* NativeModules.ModuleName.X. It is only called once for the lifetime of the
|
|
|
|
* bridge, so it is not suitable for returning dynamic values, but may be used
|
|
|
|
* for long-lived values such as session keys, that are regenerated only as
|
|
|
|
* part of a reload of the entire React application.
|
2015-02-20 04:10:52 +00:00
|
|
|
*/
|
2015-11-14 18:25:00 +00:00
|
|
|
- (NSDictionary<NSString *, id> *)constantsToExport;
|
2015-02-20 04:10:52 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Notifies the module that a batch of JS method invocations has just completed.
|
|
|
|
*/
|
|
|
|
- (void)batchDidComplete;
|
|
|
|
|
2015-12-02 13:12:17 +00:00
|
|
|
/**
|
|
|
|
* Notifies the module that the active batch of JS method invocations has been
|
|
|
|
* partially flushed.
|
|
|
|
*
|
|
|
|
* This occurs before -batchDidComplete, and more frequently.
|
|
|
|
*/
|
|
|
|
- (void)partialBatchDidFlush;
|
|
|
|
|
2015-02-20 04:10:52 +00:00
|
|
|
@end
|