react-native-macos/React/Base/RCTBridge.h

315 строки
11 KiB
C
Исходник Обычный вид История

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
2015-04-02 17:33:21 +03:00
#import <UIKit/UIKit.h>
#import <React/RCTBridgeDelegate.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTDefines.h>
#import <React/RCTFrameUpdate.h>
#import <React/RCTInvalidating.h>
@class JSValue;
@class RCTBridge;
@class RCTEventDispatcher;
@class RCTPerformanceLogger;
/**
* This notification fires when the bridge initializes.
*/
RCT_EXTERN NSString *const RCTJavaScriptWillStartLoadingNotification;
/**
* This notification fires when the bridge starts executing the JS bundle.
*/
RCT_EXTERN NSString *const RCTJavaScriptWillStartExecutingNotification;
2015-04-12 01:08:00 +03:00
/**
* This notification fires when the bridge has finished loading the JS bundle.
2015-04-12 01:08:00 +03:00
*/
RCT_EXTERN NSString *const RCTJavaScriptDidLoadNotification;
2015-04-12 01:08:00 +03:00
/**
* This notification fires when the bridge failed to load the JS bundle. The
* `error` key can be used to determine the error that occurred.
*/
RCT_EXTERN NSString *const RCTJavaScriptDidFailToLoadNotification;
/**
* This notification fires each time a native module is instantiated. The
* `module` key will contain a reference to the newly-created module instance.
* Note that this notification may be fired before the module is available via
* the `[bridge moduleForClass:]` method.
*/
RCT_EXTERN NSString *const RCTDidInitializeModuleNotification;
2019-03-22 20:39:38 +03:00
/**
* This notification fires each time a module is setup after it is initialized. The
2019-03-22 20:39:38 +03:00
* `RCTDidSetupModuleNotificationModuleNameKey` key will contain a reference to the module name and
* `RCTDidSetupModuleNotificationSetupTimeKey` will contain the setup time in ms.
*/
RCT_EXTERN NSString *const RCTDidSetupModuleNotification;
/**
* Key for the module name (NSString) in the
* RCTDidSetupModuleNotification userInfo dictionary.
*/
RCT_EXTERN NSString *const RCTDidSetupModuleNotificationModuleNameKey;
/**
* Key for the setup time (NSNumber) in the
* RCTDidSetupModuleNotification userInfo dictionary.
*/
RCT_EXTERN NSString *const RCTDidSetupModuleNotificationSetupTimeKey;
/**
* DEPRECATED - Use RCTReloadCommand instead. This notification fires just before the bridge starts
* processing a request to reload.
*/
RCT_EXTERN NSString *const RCTBridgeWillReloadNotification;
/**
* This notification fires whenever a fast refresh happens.
*/
RCT_EXTERN NSString *const RCTBridgeFastRefreshNotification;
/**
* This notification fires just before the bridge begins downloading a script
* from the packager.
*/
RCT_EXTERN NSString *const RCTBridgeWillDownloadScriptNotification;
/**
* This notification fires just after the bridge finishes downloading a script
* from the packager.
*/
RCT_EXTERN NSString *const RCTBridgeDidDownloadScriptNotification;
/**
* This notification fires right after the bridge is about to invalidate NativeModule
* instances during teardown. Handle this notification to perform additional invalidation.
*/
RCT_EXTERN NSString *const RCTBridgeWillInvalidateModulesNotification;
/**
* This notification fires right after the bridge finishes invalidating NativeModule
* instances during teardown. Handle this notification to perform additional invalidation.
*/
RCT_EXTERN NSString *const RCTBridgeDidInvalidateModulesNotification;
/**
* This notification fires right before the bridge starting invalidation process.
* Handle this notification to perform additional invalidation.
* The notification can be issued on any thread.
*/
RCT_EXTERN NSString *const RCTBridgeWillBeInvalidatedNotification;
/**
* Key for the RCTSource object in the RCTBridgeDidDownloadScriptNotification
* userInfo dictionary.
*/
RCT_EXTERN NSString *const RCTBridgeDidDownloadScriptNotificationSourceKey;
/**
* Key for the reload reason in the RCTBridgeWillReloadNotification userInfo dictionary.
*/
RCT_EXTERN NSString *const RCTBridgeDidDownloadScriptNotificationReasonKey;
/**
* Key for the bridge description (NSString_ in the
* RCTBridgeDidDownloadScriptNotification userInfo dictionary.
*/
RCT_EXTERN NSString *const RCTBridgeDidDownloadScriptNotificationBridgeDescriptionKey;
/**
* This block can be used to instantiate modules that require additional
* init parameters, or additional configuration prior to being used.
* The bridge will call this block to instantiate the modules, and will
* be responsible for invalidating/releasing them when the bridge is destroyed.
* For this reason, the block should always return new module instances, and
* module instances should not be shared between bridges.
*/
typedef NSArray<id<RCTBridgeModule>> * (^RCTBridgeModuleListProvider)(void);
/**
* These blocks are used to report whether an additional bundle
* fails or succeeds loading.
*/
typedef void (^RCTLoadAndExecuteErrorBlock)(NSError *error);
/**
* This function returns the module name for a given class.
*/
2015-04-21 15:26:51 +03:00
RCT_EXTERN NSString *RCTBridgeModuleNameForClass(Class bridgeModuleClass);
/**
* Experimental.
* Check/set if JSI-bound NativeModule is enabled. By default it's off.
*/
RCT_EXTERN BOOL RCTTurboModuleEnabled(void);
RCT_EXTERN void RCTEnableTurboModule(BOOL enabled);
// Turn on TurboModule eager initialization
RCT_EXTERN BOOL RCTTurboModuleEagerInitEnabled(void);
RCT_EXTERN void RCTEnableTurboModuleEagerInit(BOOL enabled);
/**
* Async batched bridge used to communicate with the JavaScript application.
*/
@interface RCTBridge : NSObject <RCTInvalidating>
/**
* Creates a new bridge with a custom RCTBridgeDelegate.
*
* All the interaction with the JavaScript context should be done using the bridge
* instance of the RCTBridgeModules. Modules will be automatically instantiated
* using the default contructor, but you can optionally pass in an array of
* pre-initialized module instances if they require additional init parameters
* or configuration.
*/
- (instancetype)initWithDelegate:(id<RCTBridgeDelegate>)delegate launchOptions:(NSDictionary *)launchOptions;
/**
* DEPRECATED: Use initWithDelegate:launchOptions: instead
*
* The designated initializer. This creates a new bridge on top of the specified
* executor. The bridge should then be used for all subsequent communication
* with the JavaScript code running in the executor. Modules will be automatically
* instantiated using the default contructor, but you can optionally pass in an
* array of pre-initialized module instances if they require additional init
* parameters or configuration.
*/
2015-04-12 01:08:00 +03:00
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
moduleProvider:(RCTBridgeModuleListProvider)block
launchOptions:(NSDictionary *)launchOptions;
/**
* This method is used to call functions in the JavaScript application context.
* It is primarily intended for use by modules that require two-way communication
* with the JavaScript code. Safe to call from any thread.
*/
- (void)enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args;
- (void)enqueueJSCall:(NSString *)module
method:(NSString *)method
args:(NSArray *)args
completion:(dispatch_block_t)completion;
/**
* This method registers the file path of an additional JS segment by its ID.
*
* @experimental
*/
- (void)registerSegmentWithId:(NSUInteger)segmentId path:(NSString *)path;
/**
Refactored module access to allow for lazy loading Summary: public The `bridge.modules` dictionary provides access to all native modules, but this API requires that every module is initialized in advance so that any module can be accessed. This diff introduces a better API that will allow modules to be initialized lazily as they are needed, and deprecates `bridge.modules` (modules that use it will still work, but should be rewritten to use `bridge.moduleClasses` or `-[bridge moduleForName/Class:` instead. The rules are now as follows: * Any module that overrides `init` or `setBridge:` will be initialized on the main thread when the bridge is created * Any module that implements `constantsToExport:` will be initialized later when the config is exported (the module itself will be initialized on a background queue, but `constantsToExport:` will still be called on the main thread. * All other modules will be initialized lazily when a method is first called on them. These rules may seem slightly arcane, but they have the advantage of not violating any assumptions that may have been made by existing code - any module written under the original assumption that it would be initialized synchronously on the main thread when the bridge is created should still function exactly the same, but modules that avoid overriding `init` or `setBridge:` will now be loaded lazily. I've rewritten most of the standard modules to take advantage of this new lazy loading, with the following results: Out of the 65 modules included in UIExplorer: * 16 are initialized on the main thread when the bridge is created * A further 8 are initialized when the config is exported to JS * The remaining 41 will be initialized lazily on-demand Reviewed By: jspahrsummers Differential Revision: D2677695 fb-gh-sync-id: 507ae7e9fd6b563e89292c7371767c978e928f33
2015-11-25 14:09:00 +03:00
* Retrieve a bridge module instance by name or class. Note that modules are
* lazily instantiated, so calling these methods for the first time with a given
* module name/class may cause the class to be synchronously instantiated,
* potentially blocking both the calling thread and main thread for a short time.
*
* Note: This method does NOT lazily load the particular module if it's not yet loaded.
Refactored module access to allow for lazy loading Summary: public The `bridge.modules` dictionary provides access to all native modules, but this API requires that every module is initialized in advance so that any module can be accessed. This diff introduces a better API that will allow modules to be initialized lazily as they are needed, and deprecates `bridge.modules` (modules that use it will still work, but should be rewritten to use `bridge.moduleClasses` or `-[bridge moduleForName/Class:` instead. The rules are now as follows: * Any module that overrides `init` or `setBridge:` will be initialized on the main thread when the bridge is created * Any module that implements `constantsToExport:` will be initialized later when the config is exported (the module itself will be initialized on a background queue, but `constantsToExport:` will still be called on the main thread. * All other modules will be initialized lazily when a method is first called on them. These rules may seem slightly arcane, but they have the advantage of not violating any assumptions that may have been made by existing code - any module written under the original assumption that it would be initialized synchronously on the main thread when the bridge is created should still function exactly the same, but modules that avoid overriding `init` or `setBridge:` will now be loaded lazily. I've rewritten most of the standard modules to take advantage of this new lazy loading, with the following results: Out of the 65 modules included in UIExplorer: * 16 are initialized on the main thread when the bridge is created * A further 8 are initialized when the config is exported to JS * The remaining 41 will be initialized lazily on-demand Reviewed By: jspahrsummers Differential Revision: D2677695 fb-gh-sync-id: 507ae7e9fd6b563e89292c7371767c978e928f33
2015-11-25 14:09:00 +03:00
*/
- (id)moduleForName:(NSString *)moduleName;
- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad;
// Note: This method lazily load the module as necessary.
Refactored module access to allow for lazy loading Summary: public The `bridge.modules` dictionary provides access to all native modules, but this API requires that every module is initialized in advance so that any module can be accessed. This diff introduces a better API that will allow modules to be initialized lazily as they are needed, and deprecates `bridge.modules` (modules that use it will still work, but should be rewritten to use `bridge.moduleClasses` or `-[bridge moduleForName/Class:` instead. The rules are now as follows: * Any module that overrides `init` or `setBridge:` will be initialized on the main thread when the bridge is created * Any module that implements `constantsToExport:` will be initialized later when the config is exported (the module itself will be initialized on a background queue, but `constantsToExport:` will still be called on the main thread. * All other modules will be initialized lazily when a method is first called on them. These rules may seem slightly arcane, but they have the advantage of not violating any assumptions that may have been made by existing code - any module written under the original assumption that it would be initialized synchronously on the main thread when the bridge is created should still function exactly the same, but modules that avoid overriding `init` or `setBridge:` will now be loaded lazily. I've rewritten most of the standard modules to take advantage of this new lazy loading, with the following results: Out of the 65 modules included in UIExplorer: * 16 are initialized on the main thread when the bridge is created * A further 8 are initialized when the config is exported to JS * The remaining 41 will be initialized lazily on-demand Reviewed By: jspahrsummers Differential Revision: D2677695 fb-gh-sync-id: 507ae7e9fd6b563e89292c7371767c978e928f33
2015-11-25 14:09:00 +03:00
- (id)moduleForClass:(Class)moduleClass;
Enable module lookup in TurboModules Summary: NativeModules are instantiated by the bridge. If they choose, they can capture the bridge instance that instantiated them. From within the NativeModule, the bridge can then be used to lookup other NativeModules. TurboModules have no way to do such a lookup. Both NativeModules and TurboModules need to be able to query for one another. Therefore, we have four cases: 1. NativeModule accesses NativeModule. 2. NativeModule accesses TurboModule. 3. TurboModule accesses NativeModule. 4. TurboModule accesses TurboModule. In summary, this solution extends the bridge to support querying TurboModules. It also introduces a `RCTTurboModuleLookupDelegate` protocol, which, implemented by `RCTTurboModuleManager`, supports querying TurboModules: ``` protocol RCTTurboModuleLookupDelegate <NSObject> - (id)moduleForName:(NSString *)moduleName; - (id)moduleForName:(NSString *)moduleName warnOnLookupFailure:(BOOL)warnOnLookupFailure; - (BOOL)moduleIsInitialized:(NSString *)moduleName end ``` If TurboModules want to query other TurboModules, then they need to implement this protocol and synthesize `turboModuleLookupDelegate`: ``` protocol RCTTurboModuleWithLookupCapabilities property (nonatomic, weak) id<RCTTurboModuleLookupDelegate> turboModuleLookupDelegate; end ``` NativeModules will continue to use `RCTBridge` to access other NativeModules. Nothing needs to change. When we attach the bridge to `RCTTurboModuleManager`, we also attach `RCTTurboModuleManager` to the bridge as a `RCTTurboModuleLookupDelegate`. This allows the bridge to query TurboModules, which enables our NativeModules to transparently (i.e: without any NativeModule code modification) query TurboModules. In an ideal world, all modules would be TurboModules. Until then, we're going to require that TurboModules use the bridge to query for NativeModules or TurboModules. `RCTTurboModuleManager` keeps a map of all TurboModules that we instantiated. We simply search in this map and return the TurboModule. This setup allows us to switch NativeModules to TurboModules without compromising their ability to use the bridge to search for other NativeModules (and TurboModules). When we write new TurboModules, we can have them use `RCTTurboModuleLookupDelegate` to do access other TurboModules. Eventually, after we migrate all NativeModules to TurboModules, we can migrate all old callsites to use `RCTTurboModuleLookupDelegate`. Reviewed By: fkgozali Differential Revision: D13553186 fbshipit-source-id: 4d0488eef081332c8b70782e1337eccf10717dae
2019-01-31 22:04:45 +03:00
/**
* When a NativeModule performs a lookup for a TurboModule, we need to query
* the TurboModuleRegistry.
Enable module lookup in TurboModules Summary: NativeModules are instantiated by the bridge. If they choose, they can capture the bridge instance that instantiated them. From within the NativeModule, the bridge can then be used to lookup other NativeModules. TurboModules have no way to do such a lookup. Both NativeModules and TurboModules need to be able to query for one another. Therefore, we have four cases: 1. NativeModule accesses NativeModule. 2. NativeModule accesses TurboModule. 3. TurboModule accesses NativeModule. 4. TurboModule accesses TurboModule. In summary, this solution extends the bridge to support querying TurboModules. It also introduces a `RCTTurboModuleLookupDelegate` protocol, which, implemented by `RCTTurboModuleManager`, supports querying TurboModules: ``` protocol RCTTurboModuleLookupDelegate <NSObject> - (id)moduleForName:(NSString *)moduleName; - (id)moduleForName:(NSString *)moduleName warnOnLookupFailure:(BOOL)warnOnLookupFailure; - (BOOL)moduleIsInitialized:(NSString *)moduleName end ``` If TurboModules want to query other TurboModules, then they need to implement this protocol and synthesize `turboModuleLookupDelegate`: ``` protocol RCTTurboModuleWithLookupCapabilities property (nonatomic, weak) id<RCTTurboModuleLookupDelegate> turboModuleLookupDelegate; end ``` NativeModules will continue to use `RCTBridge` to access other NativeModules. Nothing needs to change. When we attach the bridge to `RCTTurboModuleManager`, we also attach `RCTTurboModuleManager` to the bridge as a `RCTTurboModuleLookupDelegate`. This allows the bridge to query TurboModules, which enables our NativeModules to transparently (i.e: without any NativeModule code modification) query TurboModules. In an ideal world, all modules would be TurboModules. Until then, we're going to require that TurboModules use the bridge to query for NativeModules or TurboModules. `RCTTurboModuleManager` keeps a map of all TurboModules that we instantiated. We simply search in this map and return the TurboModule. This setup allows us to switch NativeModules to TurboModules without compromising their ability to use the bridge to search for other NativeModules (and TurboModules). When we write new TurboModules, we can have them use `RCTTurboModuleLookupDelegate` to do access other TurboModules. Eventually, after we migrate all NativeModules to TurboModules, we can migrate all old callsites to use `RCTTurboModuleLookupDelegate`. Reviewed By: fkgozali Differential Revision: D13553186 fbshipit-source-id: 4d0488eef081332c8b70782e1337eccf10717dae
2019-01-31 22:04:45 +03:00
*/
- (void)setRCTTurboModuleRegistry:(id<RCTTurboModuleRegistry>)turboModuleRegistry;
Enable module lookup in TurboModules Summary: NativeModules are instantiated by the bridge. If they choose, they can capture the bridge instance that instantiated them. From within the NativeModule, the bridge can then be used to lookup other NativeModules. TurboModules have no way to do such a lookup. Both NativeModules and TurboModules need to be able to query for one another. Therefore, we have four cases: 1. NativeModule accesses NativeModule. 2. NativeModule accesses TurboModule. 3. TurboModule accesses NativeModule. 4. TurboModule accesses TurboModule. In summary, this solution extends the bridge to support querying TurboModules. It also introduces a `RCTTurboModuleLookupDelegate` protocol, which, implemented by `RCTTurboModuleManager`, supports querying TurboModules: ``` protocol RCTTurboModuleLookupDelegate <NSObject> - (id)moduleForName:(NSString *)moduleName; - (id)moduleForName:(NSString *)moduleName warnOnLookupFailure:(BOOL)warnOnLookupFailure; - (BOOL)moduleIsInitialized:(NSString *)moduleName end ``` If TurboModules want to query other TurboModules, then they need to implement this protocol and synthesize `turboModuleLookupDelegate`: ``` protocol RCTTurboModuleWithLookupCapabilities property (nonatomic, weak) id<RCTTurboModuleLookupDelegate> turboModuleLookupDelegate; end ``` NativeModules will continue to use `RCTBridge` to access other NativeModules. Nothing needs to change. When we attach the bridge to `RCTTurboModuleManager`, we also attach `RCTTurboModuleManager` to the bridge as a `RCTTurboModuleLookupDelegate`. This allows the bridge to query TurboModules, which enables our NativeModules to transparently (i.e: without any NativeModule code modification) query TurboModules. In an ideal world, all modules would be TurboModules. Until then, we're going to require that TurboModules use the bridge to query for NativeModules or TurboModules. `RCTTurboModuleManager` keeps a map of all TurboModules that we instantiated. We simply search in this map and return the TurboModule. This setup allows us to switch NativeModules to TurboModules without compromising their ability to use the bridge to search for other NativeModules (and TurboModules). When we write new TurboModules, we can have them use `RCTTurboModuleLookupDelegate` to do access other TurboModules. Eventually, after we migrate all NativeModules to TurboModules, we can migrate all old callsites to use `RCTTurboModuleLookupDelegate`. Reviewed By: fkgozali Differential Revision: D13553186 fbshipit-source-id: 4d0488eef081332c8b70782e1337eccf10717dae
2019-01-31 22:04:45 +03:00
/**
* Convenience method for retrieving all modules conforming to a given protocol.
* Modules will be synchronously instantiated if they haven't already been,
* potentially blocking both the calling thread and main thread for a short time.
*/
- (NSArray *)modulesConformingToProtocol:(Protocol *)protocol;
/**
* Test if a module has been initialized. Use this prior to calling
* `moduleForClass:` or `moduleForName:` if you do not want to cause the module
* to be instantiated if it hasn't been already.
*/
- (BOOL)moduleIsInitialized:(Class)moduleClass;
Refactored module access to allow for lazy loading Summary: public The `bridge.modules` dictionary provides access to all native modules, but this API requires that every module is initialized in advance so that any module can be accessed. This diff introduces a better API that will allow modules to be initialized lazily as they are needed, and deprecates `bridge.modules` (modules that use it will still work, but should be rewritten to use `bridge.moduleClasses` or `-[bridge moduleForName/Class:` instead. The rules are now as follows: * Any module that overrides `init` or `setBridge:` will be initialized on the main thread when the bridge is created * Any module that implements `constantsToExport:` will be initialized later when the config is exported (the module itself will be initialized on a background queue, but `constantsToExport:` will still be called on the main thread. * All other modules will be initialized lazily when a method is first called on them. These rules may seem slightly arcane, but they have the advantage of not violating any assumptions that may have been made by existing code - any module written under the original assumption that it would be initialized synchronously on the main thread when the bridge is created should still function exactly the same, but modules that avoid overriding `init` or `setBridge:` will now be loaded lazily. I've rewritten most of the standard modules to take advantage of this new lazy loading, with the following results: Out of the 65 modules included in UIExplorer: * 16 are initialized on the main thread when the bridge is created * A further 8 are initialized when the config is exported to JS * The remaining 41 will be initialized lazily on-demand Reviewed By: jspahrsummers Differential Revision: D2677695 fb-gh-sync-id: 507ae7e9fd6b563e89292c7371767c978e928f33
2015-11-25 14:09:00 +03:00
/**
* All registered bridge module classes.
*/
Refactored module access to allow for lazy loading Summary: public The `bridge.modules` dictionary provides access to all native modules, but this API requires that every module is initialized in advance so that any module can be accessed. This diff introduces a better API that will allow modules to be initialized lazily as they are needed, and deprecates `bridge.modules` (modules that use it will still work, but should be rewritten to use `bridge.moduleClasses` or `-[bridge moduleForName/Class:` instead. The rules are now as follows: * Any module that overrides `init` or `setBridge:` will be initialized on the main thread when the bridge is created * Any module that implements `constantsToExport:` will be initialized later when the config is exported (the module itself will be initialized on a background queue, but `constantsToExport:` will still be called on the main thread. * All other modules will be initialized lazily when a method is first called on them. These rules may seem slightly arcane, but they have the advantage of not violating any assumptions that may have been made by existing code - any module written under the original assumption that it would be initialized synchronously on the main thread when the bridge is created should still function exactly the same, but modules that avoid overriding `init` or `setBridge:` will now be loaded lazily. I've rewritten most of the standard modules to take advantage of this new lazy loading, with the following results: Out of the 65 modules included in UIExplorer: * 16 are initialized on the main thread when the bridge is created * A further 8 are initialized when the config is exported to JS * The remaining 41 will be initialized lazily on-demand Reviewed By: jspahrsummers Differential Revision: D2677695 fb-gh-sync-id: 507ae7e9fd6b563e89292c7371767c978e928f33
2015-11-25 14:09:00 +03:00
@property (nonatomic, copy, readonly) NSArray<Class> *moduleClasses;
2015-04-21 00:04:53 +03:00
/**
* URL of the script that was loaded into the bridge.
*/
@property (nonatomic, strong, readonly) NSURL *bundleURL;
2015-04-21 00:04:53 +03:00
/**
* The class of the executor currently being used. Changes to this value will
* take effect after the bridge is reloaded.
*/
2015-04-02 17:33:21 +03:00
@property (nonatomic, strong) Class executorClass;
/**
* The delegate provided during the bridge initialization
*/
@property (nonatomic, weak, readonly) id<RCTBridgeDelegate> delegate;
/**
* The launch options that were used to initialize the bridge.
*/
2015-03-26 04:59:42 +03:00
@property (nonatomic, copy, readonly) NSDictionary *launchOptions;
/**
* Use this to check if the bridge is currently loading.
*/
2015-04-12 01:08:00 +03:00
@property (nonatomic, readonly, getter=isLoading) BOOL loading;
/**
* Use this to check if the bridge has been invalidated.
*/
@property (nonatomic, readonly, getter=isValid) BOOL valid;
/**
* Link to the Performance Logger that logs React Native perf events.
*/
@property (nonatomic, readonly, strong) RCTPerformanceLogger *performanceLogger;
/**
Refactored module access to allow for lazy loading Summary: public The `bridge.modules` dictionary provides access to all native modules, but this API requires that every module is initialized in advance so that any module can be accessed. This diff introduces a better API that will allow modules to be initialized lazily as they are needed, and deprecates `bridge.modules` (modules that use it will still work, but should be rewritten to use `bridge.moduleClasses` or `-[bridge moduleForName/Class:` instead. The rules are now as follows: * Any module that overrides `init` or `setBridge:` will be initialized on the main thread when the bridge is created * Any module that implements `constantsToExport:` will be initialized later when the config is exported (the module itself will be initialized on a background queue, but `constantsToExport:` will still be called on the main thread. * All other modules will be initialized lazily when a method is first called on them. These rules may seem slightly arcane, but they have the advantage of not violating any assumptions that may have been made by existing code - any module written under the original assumption that it would be initialized synchronously on the main thread when the bridge is created should still function exactly the same, but modules that avoid overriding `init` or `setBridge:` will now be loaded lazily. I've rewritten most of the standard modules to take advantage of this new lazy loading, with the following results: Out of the 65 modules included in UIExplorer: * 16 are initialized on the main thread when the bridge is created * A further 8 are initialized when the config is exported to JS * The remaining 41 will be initialized lazily on-demand Reviewed By: jspahrsummers Differential Revision: D2677695 fb-gh-sync-id: 507ae7e9fd6b563e89292c7371767c978e928f33
2015-11-25 14:09:00 +03:00
* Reload the bundle and reset executor & modules. Safe to call from any thread.
*/
Deprecate bridge reload API [1/n] Summary: Testing the waters with an idea for unifying RN lifecycle with/without bridge. ### Motivation/Background RN bridge is being reloaded from [several different places](https://fburl.com/codesearch/ae3zeatt). When this happens, the bridge does a bunch of things: 1. Post `RCTBridgeWillReloadNotification` (RCTSurfacePresenter listens to this and reloads) 2. Invalidate batched bridge, which does: a. invalidate display link b. post `RCTBridgeWillInvalidateModules/RCTBridgeDidInvalidateModules` (TurboModuleManager listens to this and reloads modules) c. clear js thread state d. clear some local caches 3. Set up (reload bundle and batched bridge) In a bridgeless world, there isn't one thing which owns all these peices of infra, and can reload them. ### Plan Use `RCTReloadCommand` to handle reloads. This light class previously only handled CMD+R. The new workflow looks like this: 1. Anything which cares about reloads can register itself as a listener. (RCTBridge, RCTSurfacePresenter, TurboModuleManager...) 2. Anything that previously called `bridge reload` now calls `RCTTriggerReloadCommandListeners`. 3. Delete old notifications ### Alternate Plan Use yet another NSNotification. I like `RCTReloadCommand` better. ### Unknowns Looks like we log the reason for bridge reloading [here](https://fburl.com/diffusion/lc9jj8la), do we want to save this behaviour? Does anyone look at why bridge is being reloaded cc/Rick? If so, I can add back that functionality to `RCTReloadCommand`. It should be possible to customize the order/priority of what gets reloaded first. There may be some racy behaviour that I haven't thought about yet. Changelog: [iOS][Deprecated] Deprecate [bridge reload] API - prefer RCTReloadCommand Reviewed By: shergin Differential Revision: D17869635 fbshipit-source-id: 81f39eaa2c3ce08ea1bc6f2193684c2630d81a2d
2019-10-30 22:20:29 +03:00
- (void)reload __deprecated_msg("Use RCTReloadCommand instead");
/**
* Reload the bundle and reset executor & modules. Safe to call from any thread.
*/
Deprecate bridge reload API [1/n] Summary: Testing the waters with an idea for unifying RN lifecycle with/without bridge. ### Motivation/Background RN bridge is being reloaded from [several different places](https://fburl.com/codesearch/ae3zeatt). When this happens, the bridge does a bunch of things: 1. Post `RCTBridgeWillReloadNotification` (RCTSurfacePresenter listens to this and reloads) 2. Invalidate batched bridge, which does: a. invalidate display link b. post `RCTBridgeWillInvalidateModules/RCTBridgeDidInvalidateModules` (TurboModuleManager listens to this and reloads modules) c. clear js thread state d. clear some local caches 3. Set up (reload bundle and batched bridge) In a bridgeless world, there isn't one thing which owns all these peices of infra, and can reload them. ### Plan Use `RCTReloadCommand` to handle reloads. This light class previously only handled CMD+R. The new workflow looks like this: 1. Anything which cares about reloads can register itself as a listener. (RCTBridge, RCTSurfacePresenter, TurboModuleManager...) 2. Anything that previously called `bridge reload` now calls `RCTTriggerReloadCommandListeners`. 3. Delete old notifications ### Alternate Plan Use yet another NSNotification. I like `RCTReloadCommand` better. ### Unknowns Looks like we log the reason for bridge reloading [here](https://fburl.com/diffusion/lc9jj8la), do we want to save this behaviour? Does anyone look at why bridge is being reloaded cc/Rick? If so, I can add back that functionality to `RCTReloadCommand`. It should be possible to customize the order/priority of what gets reloaded first. There may be some racy behaviour that I haven't thought about yet. Changelog: [iOS][Deprecated] Deprecate [bridge reload] API - prefer RCTReloadCommand Reviewed By: shergin Differential Revision: D17869635 fbshipit-source-id: 81f39eaa2c3ce08ea1bc6f2193684c2630d81a2d
2019-10-30 22:20:29 +03:00
- (void)reloadWithReason:(NSString *)reason __deprecated_msg("Use RCTReloadCommand instead");
Refactored module access to allow for lazy loading Summary: public The `bridge.modules` dictionary provides access to all native modules, but this API requires that every module is initialized in advance so that any module can be accessed. This diff introduces a better API that will allow modules to be initialized lazily as they are needed, and deprecates `bridge.modules` (modules that use it will still work, but should be rewritten to use `bridge.moduleClasses` or `-[bridge moduleForName/Class:` instead. The rules are now as follows: * Any module that overrides `init` or `setBridge:` will be initialized on the main thread when the bridge is created * Any module that implements `constantsToExport:` will be initialized later when the config is exported (the module itself will be initialized on a background queue, but `constantsToExport:` will still be called on the main thread. * All other modules will be initialized lazily when a method is first called on them. These rules may seem slightly arcane, but they have the advantage of not violating any assumptions that may have been made by existing code - any module written under the original assumption that it would be initialized synchronously on the main thread when the bridge is created should still function exactly the same, but modules that avoid overriding `init` or `setBridge:` will now be loaded lazily. I've rewritten most of the standard modules to take advantage of this new lazy loading, with the following results: Out of the 65 modules included in UIExplorer: * 16 are initialized on the main thread when the bridge is created * A further 8 are initialized when the config is exported to JS * The remaining 41 will be initialized lazily on-demand Reviewed By: jspahrsummers Differential Revision: D2677695 fb-gh-sync-id: 507ae7e9fd6b563e89292c7371767c978e928f33
2015-11-25 14:09:00 +03:00
/**
* Handle notifications for a fast refresh. Safe to call from any thread.
*/
- (void)onFastRefresh;
/**
* Inform the bridge, and anything subscribing to it, that it should reload.
*/
Deprecate bridge reload API [1/n] Summary: Testing the waters with an idea for unifying RN lifecycle with/without bridge. ### Motivation/Background RN bridge is being reloaded from [several different places](https://fburl.com/codesearch/ae3zeatt). When this happens, the bridge does a bunch of things: 1. Post `RCTBridgeWillReloadNotification` (RCTSurfacePresenter listens to this and reloads) 2. Invalidate batched bridge, which does: a. invalidate display link b. post `RCTBridgeWillInvalidateModules/RCTBridgeDidInvalidateModules` (TurboModuleManager listens to this and reloads modules) c. clear js thread state d. clear some local caches 3. Set up (reload bundle and batched bridge) In a bridgeless world, there isn't one thing which owns all these peices of infra, and can reload them. ### Plan Use `RCTReloadCommand` to handle reloads. This light class previously only handled CMD+R. The new workflow looks like this: 1. Anything which cares about reloads can register itself as a listener. (RCTBridge, RCTSurfacePresenter, TurboModuleManager...) 2. Anything that previously called `bridge reload` now calls `RCTTriggerReloadCommandListeners`. 3. Delete old notifications ### Alternate Plan Use yet another NSNotification. I like `RCTReloadCommand` better. ### Unknowns Looks like we log the reason for bridge reloading [here](https://fburl.com/diffusion/lc9jj8la), do we want to save this behaviour? Does anyone look at why bridge is being reloaded cc/Rick? If so, I can add back that functionality to `RCTReloadCommand`. It should be possible to customize the order/priority of what gets reloaded first. There may be some racy behaviour that I haven't thought about yet. Changelog: [iOS][Deprecated] Deprecate [bridge reload] API - prefer RCTReloadCommand Reviewed By: shergin Differential Revision: D17869635 fbshipit-source-id: 81f39eaa2c3ce08ea1bc6f2193684c2630d81a2d
2019-10-30 22:20:29 +03:00
- (void)requestReload __deprecated_msg("Use RCTReloadCommand instead");
/**
* Says whether bridge has started receiving calls from JavaScript.
*/
- (BOOL)isBatchActive;
/**
* Loads and executes additional bundles in the VM for development.
*/
- (void)loadAndExecuteSplitBundleURL:(NSURL *)bundleURL
onError:(RCTLoadAndExecuteErrorBlock)onError
onComplete:(dispatch_block_t)onComplete;
Refactored module access to allow for lazy loading Summary: public The `bridge.modules` dictionary provides access to all native modules, but this API requires that every module is initialized in advance so that any module can be accessed. This diff introduces a better API that will allow modules to be initialized lazily as they are needed, and deprecates `bridge.modules` (modules that use it will still work, but should be rewritten to use `bridge.moduleClasses` or `-[bridge moduleForName/Class:` instead. The rules are now as follows: * Any module that overrides `init` or `setBridge:` will be initialized on the main thread when the bridge is created * Any module that implements `constantsToExport:` will be initialized later when the config is exported (the module itself will be initialized on a background queue, but `constantsToExport:` will still be called on the main thread. * All other modules will be initialized lazily when a method is first called on them. These rules may seem slightly arcane, but they have the advantage of not violating any assumptions that may have been made by existing code - any module written under the original assumption that it would be initialized synchronously on the main thread when the bridge is created should still function exactly the same, but modules that avoid overriding `init` or `setBridge:` will now be loaded lazily. I've rewritten most of the standard modules to take advantage of this new lazy loading, with the following results: Out of the 65 modules included in UIExplorer: * 16 are initialized on the main thread when the bridge is created * A further 8 are initialized when the config is exported to JS * The remaining 41 will be initialized lazily on-demand Reviewed By: jspahrsummers Differential Revision: D2677695 fb-gh-sync-id: 507ae7e9fd6b563e89292c7371767c978e928f33
2015-11-25 14:09:00 +03:00
@end