Skip to content

Commit

Permalink
Interop: Introduce Bridge proxy
Browse files Browse the repository at this point in the history
Summary:
The TurboModule interop layer on iOS will ship with a Bridge proxy.

The Bridge proxy is an object that will try to simulate the Bridge's APIs, whenever possible, by delegating to Bridgeless abstractions.

## Changes
This diff introduces the Bridge proxy.
This diff starts attaching the Bridge proxy on legacy native module objects.

## How did we polyfill the APIs
The polyfills can be classified into these categories:
- implemented
- custom warning
- custom error
- default error
- deleted

When there was a sane implementation (e.g: the API belonged to [RCTCallableJSModules](https://www.internalfb.com/code/fbsource/[534223aa13d33b595edcb777189618efe20dd167]/xplat/js/react-native-github/React/Base/RCTCallableJSModules.m?lines=11), [RCTModuleRegistry](https://www.internalfb.com/code/fbsource/[9a3ba2b3176b6d1a1f161e33cec51bf892815311]/xplat/js/react-native-github/React/Base/RCTModuleRegistry.m?lines=13), [RCTBundleManager](https://www.internalfb.com/code/fbsource/[91fa1f7f49731a16aedbcd5a6740647dc21ff727]/xplat/js/react-native-github/React/Base/RCTBundleManager.m?lines=13), or [RCTBundleManager](https://www.internalfb.com/code/fbsource/[91fa1f7f49731a16aedbcd5a6740647dc21ff727]/xplat/js/react-native-github/React/Base/RCTBundleManager.m?lines=13)), it was implemented.

When it was safe to no-op the API (e.g: loading), it emit a custom warning.

When it was unsafe to call (i.e: we didn't want people calling the API) (e.g: RCTCxxBridge start), it emit a custom error.

All other APIs emit default errors.

Some APIs cannot emit errors because doing so makes the app not render: I put warnings and nooped those APIs.

I think we will have to tune these polyfills based off production crashes/results.

Reviewed By: mdvacca

Differential Revision: D46084318

fbshipit-source-id: c02535073956597a4bf91c14b1980f653cb6d3df
  • Loading branch information
RSNara authored and facebook-github-bot committed Jun 16, 2023
1 parent 3e30326 commit 7bc2b73
Show file tree
Hide file tree
Showing 25 changed files with 711 additions and 2 deletions.
7 changes: 7 additions & 0 deletions packages/react-native/Libraries/Image/RCTImageLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#import <UIKit/UIKit.h>

#import <React/RCTBridge.h>
#import <React/RCTBridgeProxy.h>
#import <React/RCTDefines.h>
#import <React/RCTImageCache.h>
#import <React/RCTImageDataDecoder.h>
Expand All @@ -34,3 +35,9 @@
@property (nonatomic, readonly) RCTImageLoader *imageLoader;

@end

@interface RCTBridgeProxy (RCTImageLoader)

@property (nonatomic, readonly) RCTImageLoader *imageLoader;

@end
9 changes: 9 additions & 0 deletions packages/react-native/Libraries/Image/RCTImageLoader.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1293,6 +1293,15 @@ - (RCTImageLoader *)imageLoader

@end

@implementation RCTBridgeProxy (RCTImageLoader)

- (RCTImageLoader *)imageLoader
{
return [self moduleForClass:[RCTImageLoader class]];
}

@end

Class RCTImageLoaderCls(void)
{
return RCTImageLoader.class;
Expand Down
7 changes: 7 additions & 0 deletions packages/react-native/Libraries/Image/RCTImageStoreManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#import <UIKit/UIKit.h>

#import <React/RCTBridge.h>
#import <React/RCTBridgeProxy.h>
#import <React/RCTURLRequestHandler.h>

@interface RCTImageStoreManager : NSObject <RCTURLRequestHandler>
Expand Down Expand Up @@ -44,3 +45,9 @@
@property (nonatomic, readonly) RCTImageStoreManager *imageStoreManager;

@end

@interface RCTBridgeProxy (RCTImageStoreManager)

@property (nonatomic, readonly) RCTImageStoreManager *imageStoreManager;

@end
9 changes: 9 additions & 0 deletions packages/react-native/Libraries/Image/RCTImageStoreManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,15 @@ - (RCTImageStoreManager *)imageStoreManager

@end

@implementation RCTBridgeProxy (RCTImageStoreManager)

- (RCTImageStoreManager *)imageStoreManager
{
return [self moduleForClass:[RCTImageStoreManager class]];
}

@end

Class RCTImageStoreManagerCls(void)
{
return RCTImageStoreManager.class;
Expand Down
7 changes: 7 additions & 0 deletions packages/react-native/Libraries/Network/RCTNetworking.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/

#import <React/RCTBridgeProxy.h>
#import <React/RCTEventEmitter.h>
#import <React/RCTNetworkTask.h>
#import <React/RCTURLRequestHandler.h>
Expand Down Expand Up @@ -61,6 +62,12 @@

@end

@interface RCTBridgeProxy (RCTNetworking)

@property (nonatomic, readonly) RCTNetworking *networking;

@end

// HACK: When uploading images/video from PHAssetLibrary, we change the URL scheme to be
// ph-upload://. This is to ensure that we upload a full video when given a ph-upload:// URL,
// instead of just the thumbnail. Consider the following problem:
Expand Down
9 changes: 9 additions & 0 deletions packages/react-native/Libraries/Network/RCTNetworking.mm
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,15 @@ - (RCTNetworking *)networking

@end

@implementation RCTBridgeProxy (RCTNetworking)

- (RCTNetworking *)networking
{
return [self moduleForClass:[RCTNetworking class]];
}

@end

Class RCTNetworkingCls(void)
{
return RCTNetworking.class;
Expand Down
35 changes: 35 additions & 0 deletions packages/react-native/React/Base/RCTBridgeProxy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#import <Foundation/Foundation.h>

#import "RCTBridgeModule.h"

@class RCTBundleManager;
@class RCTCallableJSModules;
@class RCTModuleRegistry;
@class RCTViewRegistry;

@interface RCTBridgeProxy : NSProxy
- (instancetype)initWithViewRegistry:(RCTViewRegistry *)viewRegistry
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
bundleManager:(RCTBundleManager *)bundleManager
callableJSModules:(RCTCallableJSModules *)callableJSModules
dispatchToJSThread:(void (^)(dispatch_block_t))dispatchToJSThread NS_DESIGNATED_INITIALIZER;

- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel;
- (void)forwardInvocation:(NSInvocation *)invocation;

- (void)logWarning:(NSString *)message cmd:(SEL)cmd;
- (void)logError:(NSString *)message cmd:(SEL)cmd;

/**
* Methods required for RCTBridge class extensions
*/
- (id)moduleForClass:(Class)moduleClass;
- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad;
@end
Loading

0 comments on commit 7bc2b73

Please sign in to comment.