1 // Copyright 2022-present 650 Industries. All rights reserved.
2 
3 import React
4 import Foundation
5 
6 /**
7  The classic bridge module that is responsible for:
8  - Creating and owning the `AppContext` when the Expo modules architecture is automatically initialized
9    by React Native (as opposed to native unit tests, where React Native is not used at all).
10  - Installing the host object to the runtime.
11  */
12 @objc(ExpoBridgeModule)
13 public final class ExpoBridgeModule: NSObject, RCTBridgeModule {
14   @objc
15   public let appContext: AppContext
16 
17   /**
18    The initializer that is used by React Native when it loads bridge modules.
19    In this scenario, we create an `AppContext` that manages the
20    architecture of Expo modules and the app itself.
21    */
22   override init() {
23     appContext = AppContext()
24     super.init()
25   }
26 
27   deinit {
28     NotificationCenter.default.removeObserver(self)
29   }
30 
31   // MARK: - RCTBridgeModule
32 
33   public static func moduleName() -> String! {
34     return "Expo"
35   }
36 
37   public static func requiresMainQueueSetup() -> Bool {
38     return true
39   }
40 
41   public var bridge: RCTBridge! {
42     didSet {
43       appContext.reactBridge = bridge
44       bridge.dispatchBlock({ [weak self] in
45         guard let self = self, let bridge = self.appContext.reactBridge else {
46           return
47         }
48         self.appContext.runtime = EXJavaScriptRuntimeManager.runtime(fromBridge: bridge)
49       }, queue: RCTJSThread)
50     }
51   }
52 
53   /**
54    This should be called inside EXNativeModulesProxy.setBridge()
55    */
56   @objc
57   public func legacyProxyDidSetBridge(legacyModulesProxy: LegacyNativeModulesProxy,
58                                       legacyModuleRegistry: EXModuleRegistry) {
59     appContext.legacyModuleRegistry = legacyModuleRegistry
60     appContext.legacyModulesProxy = legacyModulesProxy
61 
62     // we need to register all the modules after the legacy module registry is set
63     // otherwise legacy modules (e.g. permissions) won't be available in OnCreate { }
64     appContext.useModulesProvider("ExpoModulesProvider")
65     appContext.moduleRegistry.register(moduleType: NativeModulesProxyModule.self)
66   }
67 }
68