1// Copyright 2018-present 650 Industries. All rights reserved.
2
3#import <ExpoModulesCore/EXNativeModulesProxy.h>
4#import <ExpoModulesCore/EXViewManagerAdapter.h>
5#import <ExpoModulesCore/EXModuleRegistryAdapter.h>
6#import <ExpoModulesCore/EXViewManagerAdapterClassesRegistry.h>
7#import <ExpoModulesCore/EXModuleRegistryHolderReactModule.h>
8
9@interface EXModuleRegistryAdapter ()
10
11@property (nonatomic, strong) EXModuleRegistryProvider *moduleRegistryProvider;
12@property (nonatomic, strong) EXViewManagerAdapterClassesRegistry *viewManagersClassesRegistry;
13@property (nonatomic, strong, nullable) Class swiftModulesProviderClass;
14
15@end
16
17@implementation EXModuleRegistryAdapter
18
19- (instancetype)initWithModuleRegistryProvider:(EXModuleRegistryProvider *)moduleRegistryProvider
20{
21  if (self = [super init]) {
22    _moduleRegistryProvider = moduleRegistryProvider;
23    _viewManagersClassesRegistry = [[EXViewManagerAdapterClassesRegistry alloc] init];
24  }
25  return self;
26}
27
28- (instancetype)initWithModuleRegistryProvider:(EXModuleRegistryProvider *)moduleRegistryProvider swiftModulesProviderClass:(nullable Class)swiftModulesProviderClass
29{
30  if (self = [self initWithModuleRegistryProvider:moduleRegistryProvider]) {
31    _swiftModulesProviderClass = swiftModulesProviderClass;
32  }
33  return self;
34}
35
36- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
37{
38  return [self extraModulesForModuleRegistry:[_moduleRegistryProvider moduleRegistry]];
39}
40
41- (NSArray<id<RCTBridgeModule>> *)extraModulesForModuleRegistry:(EXModuleRegistry *)moduleRegistry
42{
43  NSMutableArray<id<RCTBridgeModule>> *extraModules = [NSMutableArray array];
44
45  EXNativeModulesProxy *nativeModulesProxy = [[EXNativeModulesProxy alloc] initWithModuleRegistry:moduleRegistry swiftModulesProviderClass:_swiftModulesProviderClass];
46
47  [extraModules addObject:nativeModulesProxy];
48
49  for (EXViewManager *viewManager in [moduleRegistry getAllViewManagers]) {
50    Class viewManagerAdapterClass = [_viewManagersClassesRegistry viewManagerAdapterClassForViewManager:viewManager];
51    [extraModules addObject:[[viewManagerAdapterClass alloc] initWithViewManager:viewManager]];
52  }
53
54  // Silence React Native warning `Base module "%s" does not exist`
55  // occurring when view manager class is subclassing another class
56  // that is not RCTViewManager (in our case all the view manager adapters
57  // subclass EXViewManagerAdapter, so RN expects to find EXViewManagerAdapter
58  // exported.
59  [extraModules addObject:[[EXViewManagerAdapter alloc] init]];
60
61  // It is possible that among internal modules there are some RCTBridgeModules --
62  // let's add them to extraModules here.
63  for (id<EXInternalModule> module in [moduleRegistry getAllInternalModules]) {
64    if ([module conformsToProtocol:@protocol(RCTBridgeModule)]) {
65      id<RCTBridgeModule> reactBridgeModule = (id<RCTBridgeModule>)module;
66      [extraModules addObject:reactBridgeModule];
67    }
68  }
69
70  // Adding the way to access the module registry from RCTBridgeModules.
71  [extraModules addObject:[[EXModuleRegistryHolderReactModule alloc] initWithModuleRegistry:moduleRegistry]];
72
73  // One could add some modules to the Module Registry after creating it.
74  // Here is our last call for finalizing initialization.
75  [moduleRegistry initialize];
76  return extraModules;
77}
78
79@end
80