1// Copyright 2015-present 650 Industries. All rights reserved. 2 3#import <EXDevLauncher/EXDevLauncherRCTBridge.h> 4#import <EXDevLauncher/EXDevLauncherController.h> 5#import <EXDevLauncher/RCTCxxBridge+Private.h> 6 7#import <React/RCTPerformanceLogger.h> 8#import <React/RCTDevSettings.h> 9#import <React/RCTDevMenu.h> 10 11@import EXDevMenuInterface; 12 13@implementation EXDevLauncherRCTCxxBridge 14 15- (instancetype)initWithParentBridge:(RCTBridge *)bridge 16{ 17 if ((self = [super initWithParentBridge:bridge])) { 18 RCTBridge *appBridge = [EXDevLauncherController sharedInstance].appBridge; 19 // reset the singleton `RCTBridge.currentBridge` to app bridge instance 20 RCTBridge.currentBridge = appBridge != nil ? appBridge.batchedBridge : nil; 21 } 22 return self; 23} 24 25/** 26 * Theoretically, we could overwrite the `RCTDevSettings` module by exporting our version through the bridge. 27 * However, this won't work with the js remote debugging. For some reason, the RN needs to initialized remote tools very early. So it always uses the default module to do it. 28 * When we export our module, it won't be used in the initialized phase. So the launcher will start with remote debug support. 29 */ 30- (RCTDevSettings *)devSettings 31{ 32#ifdef EX_DEV_LAUNCHER_URL 33 return super.devSettings; 34#endif 35 return nil; 36} 37 38- (RCTDevMenu *)devMenu 39{ 40 return nil; 41} 42 43- (NSArray<Class> *)filterModuleList:(NSArray<Class> *)modules 44{ 45 NSArray<NSString *> *allowedModules = @[@"RCT", @"DevMenu", @"ExpoBridgeModule", @"EXNativeModulesProxy", @"ViewManagerAdapter_", @"EXReactNativeEventEmitter"]; 46 NSArray<Class> *filteredModuleList = [modules filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nullable clazz, NSDictionary<NSString *,id> * _Nullable bindings) { 47 if ([clazz conformsToProtocol:@protocol(DevMenuExtensionProtocol)]) { 48 return true; 49 } 50 51 if ([clazz conformsToProtocol:@protocol(EXDevExtensionProtocol)]) { 52 return true; 53 } 54 55 NSString* clazzName = NSStringFromClass(clazz); 56 for (NSString *allowedModule in allowedModules) { 57 if ([clazzName hasPrefix:allowedModule]) { 58 return true; 59 } 60 } 61 return false; 62 }]]; 63 64 return filteredModuleList; 65} 66 67- (NSArray<RCTModuleData *> *)_initializeModules:(NSArray<Class> *)modules 68 withDispatchGroup:(dispatch_group_t)dispatchGroup 69 lazilyDiscovered:(BOOL)lazilyDiscovered 70{ 71 return [super _initializeModules:[self filterModuleList:modules] withDispatchGroup:dispatchGroup lazilyDiscovered:lazilyDiscovered]; 72} 73 74@end 75 76@implementation EXDevLauncherRCTBridge 77 78- (Class)bridgeClass 79{ 80 return [EXDevLauncherRCTCxxBridge class]; 81} 82 83#pragma clang diagnostic push 84#pragma clang diagnostic ignored "-Wdeprecated-implementations" 85// This method is still used so we need to override it even if it's deprecated 86- (void)reloadWithReason:(NSString *)reason {} 87#pragma clang diagnostic pop 88 89@end 90