1 // Copyright 2015-present 650 Industries. All rights reserved. 2 3 class DevMenuAppInstance: NSObject, RCTBridgeDelegate { 4 static private var CloseEventName = "closeDevMenu" 5 6 private let manager: DevMenuManager 7 8 var bridge: RCTBridge? 9 10 init(manager: DevMenuManager) { 11 self.manager = manager 12 13 super.init() 14 15 self.bridge = DevMenuRCTBridge.init(delegate: self, launchOptions: nil) 16 } 17 18 /** 19 Sends an event to JS triggering the animation that collapses the dev menu. 20 */ 21 public func sendCloseEvent() { 22 bridge?.enqueueJSCall("RCTDeviceEventEmitter.emit", args: [DevMenuAppInstance.CloseEventName]) 23 } 24 25 // MARK: RCTBridgeDelegate 26 27 func sourceURL(for bridge: RCTBridge!) -> URL! { 28 #if DEBUG 29 if let packagerHost = jsPackagerHost() { 30 return RCTBundleURLProvider.jsBundleURL(forBundleRoot: "index", packagerHost: packagerHost, enableDev: true, enableMinification: false) 31 } 32 #endif 33 return jsSourceUrl() 34 } 35 36 func extraModules(for bridge: RCTBridge!) -> [RCTBridgeModule]! { 37 var modules: [RCTBridgeModule] = [DevMenuInternalModule(manager: manager)] 38 modules.append(contentsOf: DevMenuVendoredModulesUtils.vendoredModules()) 39 modules.append(MockedRNCSafeAreaProvider.init()) 40 modules.append(DevMenuLoadingView.init()) 41 return modules 42 } 43 44 func bridge(_ bridge: RCTBridge!, didNotFindModule moduleName: String!) -> Bool { 45 return moduleName == "DevMenu" 46 } 47 48 // MARK: private 49 50 private func jsSourceUrl() -> URL? { 51 return DevMenuUtils.resourcesBundle()?.url(forResource: "EXDevMenuApp.ios", withExtension: "js") 52 } 53 54 private func jsPackagerHost() -> String? { 55 // Return `nil` if resource doesn't exist in the bundle. 56 guard let packagerHostPath = DevMenuUtils.resourcesBundle()?.path(forResource: "dev-menu-packager-host", ofType: nil) else { 57 return nil 58 } 59 // Return `nil` if the content is not a valid URL. 60 guard let content = try? String(contentsOfFile: packagerHostPath, encoding: String.Encoding.utf8).trimmingCharacters(in: CharacterSet.newlines), 61 let url = URL(string: content) else { 62 return nil 63 } 64 return url.absoluteString 65 } 66 } 67