44//
55// Created by tconns94 on 8/21/2025.
66//
7-
87import UIKit
98import Foundation
109import React
1110
1211class NitroRestart : HybridNitroRestartSpec {
1312 func restartApp( moduleName: String ) {
1413 DispatchQueue . main. async {
15- guard let appDelegate = UIApplication . shared. delegate as? RCTAppDelegate ,
16- let bridge = appDelegate. bridge,
17- let window = appDelegate. window else {
18- print ( " NitroRestart Error: Unable to access app delegate, bridge, or window " )
14+ guard let appDelegate = UIApplication . shared. delegate else {
15+ print ( " NitroRestart Error: Unable to access app delegate " )
16+ return
17+ }
18+
19+ // Try to get window and factory using reflection
20+ guard let window = ( appDelegate as? NSObject ) ? . value ( forKey: " window " ) as? UIWindow ,
21+ let factory = ( appDelegate as? NSObject ) ? . value ( forKey: " reactNativeFactory " ) else {
22+ print ( " NitroRestart Error: Unable to access window or React Native factory " )
1923 return
2024 }
2125
22- let rootView = RCTRootView (
23- bridge: bridge,
24- moduleName: moduleName,
25- initialProperties: nil
26- )
27- let vc = UIViewController ( )
28- vc. view = rootView
29- window. rootViewController = vc
30- window. makeKeyAndVisible ( )
26+ // Use reflection to call startReactNative method
27+ let factoryObject = factory as AnyObject
28+ let selector = Selector ( ( " startReactNative:in:launchOptions: " ) )
29+ if factoryObject. responds ( to: selector) {
30+ let method = factoryObject. method ( for: selector)
31+ typealias StartReactNativeMethod = @convention ( c) ( AnyObject , Selector , String , UIWindow , [ UIApplication . LaunchOptionsKey : Any ] ? ) -> Void
32+ let startReactNative = unsafeBitCast ( method, to: StartReactNativeMethod . self)
33+ startReactNative ( factoryObject, selector, moduleName, window, nil )
34+ } else {
35+ print ( " NitroRestart Error: startReactNative method not found " )
36+ }
3137 }
3238 }
3339
3440 func exitApp( ) {
3541 DispatchQueue . main. async {
36- // Note: Direct app termination violates iOS guidelines and may cause App Store rejection
37- // This implementation suspends the app instead of terminating it
38- if let window = UIApplication . shared. windows. first {
39- UIView . animate ( withDuration: 0.3 , animations: {
40- window. alpha = 0
41- window. transform = CGAffineTransform ( scaleX: 0.8 , y: 0.8 )
42- } ) { _ in
43- // Put app in suspended state (safer than exit)
44- UIApplication . shared. perform ( #selector( NSXPCConnection . suspend) )
45- }
42+ guard
43+ let scene = UIApplication . shared. connectedScenes. first as? UIWindowScene ,
44+ let window = scene. windows. first
45+ else { return }
46+
47+ UIView . animate ( withDuration: 0.3 , animations: {
48+ window. alpha = 0
49+ window. transform = CGAffineTransform ( scaleX: 0.8 , y: 0.8 )
50+ } ) { _ in
51+ // ⚠️ Lưu ý: Vi phạm guideline App Store nếu đưa lên store
52+ // Chỉ nên dùng trong app nội bộ hoặc dev
53+ UIApplication . shared. perform ( #selector( NSXPCConnection . suspend) )
4654 }
4755 }
4856 }
4957
5058 func getPid( ) -> Double {
51- return Double ( getpid ( ) )
59+ return Double ( getpid ( ) )
5260 }
53- }
61+ }
0 commit comments