Skip to content

Commit

Permalink
Make the Fabric Interop Layer automatic (#41656)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #41656

This change makes all the legacy components to go through the interop layer.
It also introduce the `RCTFabricInteropLayerEnabled()` and the `RCTEnableFabricInteropLayer(BOOL)` functions to work as feature flags behind the change to completely disable the Interop layer.

## Changelog
[iOS][Changed] - Make the Fabric Interop Layer automatic when the Nw architecture is enabled.

Reviewed By: cortinico

Differential Revision: D51586461

fbshipit-source-id: 8f92a76e6dbbee93055a1ebe49779dd64e484d95
  • Loading branch information
cipolleschi authored and facebook-github-bot committed Dec 18, 2023
1 parent 32dab7a commit 27f38f6
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 220 deletions.
12 changes: 0 additions & 12 deletions packages/react-native/Libraries/AppDelegate/RCTAppDelegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#import <React/RCTSurfacePresenterBridgeAdapter.h>
#import <react/renderer/runtimescheduler/RuntimeScheduler.h>
#import "RCTAppSetupUtils.h"
#import "RCTLegacyInteropComponents.h"

#if RN_DISABLE_OSS_PLUGIN_HEADER
#import <RCTTurboModulePlugin/RCTTurboModulePlugin.h>
Expand All @@ -22,7 +21,6 @@
#import <React/RCTComponentViewFactory.h>
#import <React/RCTComponentViewProtocol.h>
#import <React/RCTFabricSurface.h>
#import <React/RCTLegacyViewManagerInteropComponentView.h>
#import <React/RCTSurfaceHostingProxyRootView.h>
#import <React/RCTSurfacePresenter.h>
#import <ReactCommon/RCTContextContainerHandling.h>
Expand Down Expand Up @@ -98,7 +96,6 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
RCTEnableTurboModuleInteropBridgeProxy(YES);

[self createReactHost];
[self unstable_registerLegacyComponents];
[RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self;
RCTFabricSurface *surface = [_reactHost createSurfaceWithModuleName:self.moduleName initialProperties:initProps];

Expand All @@ -116,10 +113,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
contextContainer:_contextContainer];
self.bridge.surfacePresenter = self.bridgeAdapter.surfacePresenter;

[self unstable_registerLegacyComponents];
[RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self;
}

rootView = [self createRootViewWithBridge:self.bridge moduleName:self.moduleName initProps:initProps];
}
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
Expand Down Expand Up @@ -267,13 +262,6 @@ - (Class)getModuleClassFromName:(const char *)name

#pragma mark - New Arch Utilities

- (void)unstable_registerLegacyComponents
{
for (NSString *legacyComponent in [RCTLegacyInteropComponents legacyInteropComponents]) {
[RCTLegacyViewManagerInteropComponentView supportLegacyViewManagerWithName:legacyComponent];
}
}

- (void)createReactHost
{
__weak __typeof(self) weakSelf = self;
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -94,19 +94,4 @@ Pod::Spec.new do |s|
else
s.dependency "React-jsc"
end

rel_path_from_pods_root_to_app = Pathname.new(ENV['APP_PATH']).relative_path_from(Pod::Config.instance.installation_root)
rel_path_from_pods_to_app = Pathname.new(ENV['APP_PATH']).relative_path_from(File.join(Pod::Config.instance.installation_root, 'Pods'))

s.script_phases = {
:name => "Generate Legacy Components Interop",
:script => "
WITH_ENVIRONMENT=\"$REACT_NATIVE_PATH/scripts/xcode/with-environment.sh\"
source $WITH_ENVIRONMENT
${NODE_BINARY} ${REACT_NATIVE_PATH}/scripts/codegen/generate-legacy-interop-components.js -p #{rel_path_from_pods_to_app} -o ${REACT_NATIVE_PATH}/Libraries/AppDelegate
",
:execution_position => :before_compile,
:input_files => ["#{rel_path_from_pods_root_to_app}/react-native.config.js"],
:output_files => ["${REACT_NATIVE_PATH}/Libraries/AppDelegate/RCTLegacyInteropComponents.mm"],
}
end
4 changes: 4 additions & 0 deletions packages/react-native/React/Base/RCTBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ void RCTEnableTurboModuleInterop(BOOL enabled);
BOOL RCTTurboModuleInteropBridgeProxyEnabled(void);
void RCTEnableTurboModuleInteropBridgeProxy(BOOL enabled);

// Turn on the fabric interop layer
BOOL RCTFabricInteropLayerEnabled(void);
void RCTEnableFabricInteropLayer(BOOL enabled);

// Turn on TurboModule sync execution of void methods
BOOL RCTTurboModuleSyncVoidMethodsEnabled(void);
void RCTEnableTurboModuleSyncVoidMethods(BOOL enabled);
Expand Down
11 changes: 11 additions & 0 deletions packages/react-native/React/Base/RCTBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,17 @@ void RCTEnableTurboModuleInteropBridgeProxy(BOOL enabled)
turboModuleInteropBridgeProxyEnabled = enabled;
}

static BOOL fabricInteropLayerEnabled = YES;
BOOL RCTFabricInteropLayerEnabled()
{
return fabricInteropLayerEnabled;
}

void RCTEnableFabricInteropLayer(BOOL enabled)
{
fabricInteropLayerEnabled = enabled;
}

static RCTBridgeProxyLoggingLevel bridgeProxyLoggingLevel = kRCTBridgeProxyLoggingLevelNone;
RCTBridgeProxyLoggingLevel RCTTurboModuleInteropBridgeProxyLogLevel(void)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#import "RCTLegacyViewManagerInteropComponentView.h"

#import <React/RCTAssert.h>
#import <React/RCTBridge+Private.h>
#import <React/RCTConstants.h>
#import <React/UIView+React.h>
#import <react/renderer/components/legacyviewmanagerinterop/LegacyViewManagerInteropComponentDescriptor.h>
Expand Down Expand Up @@ -106,6 +107,12 @@ - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
return supported;
}

+ (NSMutableDictionary<NSString *, Class> *)_supportedLegacyViewComponents
{
static NSMutableDictionary<NSString *, Class> *suppoerted = [NSMutableDictionary new];
return suppoerted;
}

+ (BOOL)isSupported:(NSString *)componentName
{
// Step 1: check if ViewManager with specified name is supported.
Expand All @@ -122,6 +129,29 @@ + (BOOL)isSupported:(NSString *)componentName
}
}

// Step 3: check if the module has been registered
NSArray<Class> *registeredModules = RCTGetModuleClasses();
NSMutableDictionary<NSString *, Class> *supportedLegacyViewComponents =
[RCTLegacyViewManagerInteropComponentView _supportedLegacyViewComponents];
if (supportedLegacyViewComponents[componentName] != NULL) {
return YES;
}

for (Class moduleClass in registeredModules) {
id<RCTBridgeModule> bridgeModule = (id<RCTBridgeModule>)moduleClass;
NSString *moduleName = [[bridgeModule moduleName] isEqualToString:@""]
? [NSStringFromClass(moduleClass) stringByReplacingOccurrencesOfString:@"Manager" withString:@""]
: [bridgeModule moduleName];

if (supportedLegacyViewComponents[moduleName] == NULL) {
supportedLegacyViewComponents[moduleName] = moduleClass;
}

if ([moduleName isEqualToString:componentName]) {
return YES;
}
}

return NO;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#import "RCTComponentViewFactory.h"

#import <React/RCTAssert.h>
#import <React/RCTBridge.h>
#import <React/RCTConversions.h>
#import <React/RCTLog.h>

Expand Down Expand Up @@ -110,12 +111,11 @@ - (BOOL)registerComponentIfPossible:(const std::string &)name
// when the component is registered in both Fabric and in the
// interop layer, so they can remove that
NSString *componentNameString = RCTNSStringFromString(name);
BOOL isRegisteredInInteropLayer = [RCTLegacyViewManagerInteropComponentView isSupported:componentNameString];

// Fallback 1: Call provider function for component view class.
Class<RCTComponentViewProtocol> klass = RCTComponentViewClassWithName(name.c_str());
if (klass) {
[self registerComponentViewClass:klass andWarnIfNeeded:isRegisteredInInteropLayer];
[self registerComponentViewClass:klass];
return YES;
}

Expand All @@ -126,13 +126,13 @@ - (BOOL)registerComponentIfPossible:(const std::string &)name
NSString *objcName = [NSString stringWithCString:name.c_str() encoding:NSUTF8StringEncoding];
klass = self.thirdPartyFabricComponentsProvider.thirdPartyFabricComponents[objcName];
if (klass) {
[self registerComponentViewClass:klass andWarnIfNeeded:isRegisteredInInteropLayer];
[self registerComponentViewClass:klass];
return YES;
}
}

// Fallback 3: Try to use Paper Interop.
if (isRegisteredInInteropLayer) {
if (RCTFabricInteropLayerEnabled() && [RCTLegacyViewManagerInteropComponentView isSupported:componentNameString]) {
RCTLogNewArchitectureValidation(
RCTNotAllowedInBridgeless,
self,
Expand Down Expand Up @@ -221,17 +221,4 @@ - (RCTComponentViewDescriptor)createComponentViewWithComponentHandle:(facebook::
return _providerRegistry.createComponentDescriptorRegistry(parameters);
}

#pragma mark - Private

- (void)registerComponentViewClass:(Class<RCTComponentViewProtocol>)componentViewClass
andWarnIfNeeded:(BOOL)isRegisteredInInteropLayer
{
[self registerComponentViewClass:componentViewClass];
if (isRegisteredInInteropLayer) {
RCTLogWarn(
@"Component with class %@ has been registered in both the New Architecture Renderer and in the Interop Layer.\nPlease remove it from the Interop Layer",
componentViewClass);
}
}

@end

This file was deleted.

4 changes: 0 additions & 4 deletions packages/rn-tester/react-native.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ module.exports = {
project: {
ios: {
sourceDir: '.',
unstable_reactLegacyComponentNames: [
'RNTMyLegacyNativeView',
'RNTMyNativeView',
],
},
android: {
sourceDir: '../../',
Expand Down

0 comments on commit 27f38f6

Please sign in to comment.