1 // Copyright 2015-present 650 Industries. All rights reserved.
2 
3 import Foundation
4 
5 @objc
6 public class EXDevLauncherRedBoxInterceptor: NSObject {
7   @objc static let customRedBox = EXDevLauncherRedBox()
8 
9   @objc
10   public static var isInstalled: Bool = false {
11     willSet {
12       if isInstalled != newValue {
13         swizzle()
14       }
15     }
16   }
17 
swizzlenull18   static private func swizzle() {
19     EXDevLauncherUtils.swizzle(
20       selector: #selector(RCTCxxBridge.module(forName:)),
21       withSelector: #selector(RCTCxxBridge.EXDevLauncher_module(forName:)),
22       forClass: RCTCxxBridge.self
23     )
24 
25     EXDevLauncherUtils.swizzle(
26       selector: #selector(RCTCxxBridge.module(forName:lazilyLoadIfNecessary:)),
27       withSelector: #selector(RCTCxxBridge.EXDevLauncher_module(forName:lazilyLoadIfNecessary:)),
28       forClass: RCTCxxBridge.self
29     )
30 
31     EXDevLauncherUtils.swizzle(
32       selector: #selector(RCTCxxBridge.module(for:)),
33       withSelector: #selector(RCTCxxBridge.EXDevLauncher_module(forClass:)),
34       forClass: RCTCxxBridge.self
35     )
36   }
37 }
38 
39 extension RCTCxxBridge {
40   @objc
EXDevLauncher_modulenull41   func EXDevLauncher_module(forName name: String) -> Any? {
42     let orginalModule = self.EXDevLauncher_module(forName: name)
43     return replaceRedBox(orginalModule)
44   }
45 
46   @objc
EXDevLauncher_modulenull47   func EXDevLauncher_module(forName name: String, lazilyLoadIfNecessary lazilyLoad: Bool) -> Any? {
48     let orginalModule = self.EXDevLauncher_module(forName: name, lazilyLoadIfNecessary: lazilyLoad)
49     return replaceRedBox(orginalModule)
50   }
51 
52   @objc
EXDevLauncher_modulenull53   func EXDevLauncher_module(forClass clazz: Any) -> Any? {
54     let orginalModule = self.EXDevLauncher_module(forClass: clazz)
55     return replaceRedBox(orginalModule)
56   }
57 
58   @objc
replaceRedBoxnull59   private func replaceRedBox(_ module: Any?) -> Any? {
60     if module is RCTRedBox {
61       let logBox = EXDevLauncher_module(forClass: RCTLogBox.self) as? RCTLogBox
62       let customRedBox = EXDevLauncherRedBoxInterceptor.customRedBox
63       customRedBox.register(logBox)
64       return customRedBox.unsafe_castToRCTRedBox()
65     }
66 
67     return module
68   }
69 }
70