1 // Copyright 2015-present 650 Industries. All rights reserved.
2 
3 import React
4 
5 @objc
6 class DevMenuAppInstance: DevMenuRCTAppDelegate {
7   static private var CloseEventName = "closeDevMenu"
8   static private var OpenEventName = "openDevMenu"
9 
10   private let manager: DevMenuManager
11 
12 
13   init(manager: DevMenuManager) {
14     self.manager = manager
15 
16     super.init()
17     self.createBridgeAndSetAdapter(launchOptions: nil)
18   }
19 
20   init(manager: DevMenuManager, bridge: RCTBridge) {
21     self.manager = manager
22 
23     super.init()
24 
25     self.bridge = bridge
26   }
27 
28   /**
29    Sends an event to JS triggering the animation that collapses the dev menu.
30    */
sendCloseEventnull31   public func sendCloseEvent() {
32     bridge?.enqueueJSCall("RCTDeviceEventEmitter.emit", args: [DevMenuAppInstance.CloseEventName])
33   }
34 
sendOpenEventnull35   public func sendOpenEvent() {
36     bridge?.enqueueJSCall("RCTDeviceEventEmitter.emit", args: [DevMenuAppInstance.OpenEventName])
37   }
38 
39   // MARK: RCTAppDelegate
40 
41   // swiftlint:disable implicitly_unwrapped_optional
sourceURLnull42   override func sourceURL(for bridge: RCTBridge!) -> URL! {
43     #if DEBUG
44     if let packagerHost = jsPackagerHost() {
45       return RCTBundleURLProvider.jsBundleURL(
46         forBundleRoot: "index",
47         packagerHost: packagerHost,
48         enableDev: true,
49         enableMinification: false)
50     }
51     #endif
52     return jsSourceUrl()
53   }
54 
extraModulesnull55   override func extraModules(for bridge: RCTBridge!) -> [RCTBridgeModule]! {
56     var modules: [RCTBridgeModule] = [DevMenuLoadingView.init()]
57     modules.append(DevMenuRCTDevSettings.init())
58     return modules
59   }
60 
bridgenull61   override func bridge(_ bridge: RCTBridge!, didNotFindModule moduleName: String!) -> Bool {
62     return moduleName == "DevMenu"
63   }
64   // swiftlint:enable implicitly_unwrapped_optional
65 
66   // MARK: private
67 
jsSourceUrlnull68   private func jsSourceUrl() -> URL? {
69     return DevMenuUtils.resourcesBundle()?.url(forResource: "EXDevMenuApp.ios", withExtension: "js")
70   }
71 
jsPackagerHostnull72   private func jsPackagerHost() -> String? {
73     // Return `nil` if resource doesn't exist in the bundle.
74     guard let packagerHostPath = DevMenuUtils.resourcesBundle()?.path(forResource: "dev-menu-packager-host", ofType: nil) else {
75       return nil
76     }
77     // Return `nil` if the content is not a valid URL.
78     guard let content = try? String(contentsOfFile: packagerHostPath, encoding: String.Encoding.utf8).trimmingCharacters(in: CharacterSet.newlines),
79       let url = URL(string: content) else {
80       return nil
81     }
82     return url.absoluteString
83   }
84 }
85