1414#import < React/RCTEventDispatcherProtocol.h>
1515#import < React/RCTInitializing.h>
1616#import < React/RCTInvalidating.h>
17- #import < React/RCTKeyWindowValuesProxy.h>
1817#import < React/RCTUtils.h>
19- #import < React/RCTWindowSafeAreaProxy.h>
2018#import < atomic>
2119
2220#import " CoreModulesPlugins.h"
@@ -31,23 +29,40 @@ @implementation RCTDeviceInfo {
3129 NSDictionary *_currentInterfaceDimensions;
3230 BOOL _isFullscreen;
3331 std::atomic<BOOL > _invalidated;
32+ NSDictionary *_constants;
33+
34+ __weak UIWindow *_applicationWindow;
3435}
3536
37+ static NSString *const kFrameKeyPath = @" frame" ;
38+
3639@synthesize moduleRegistry = _moduleRegistry;
3740
3841RCT_EXPORT_MODULE ()
3942
4043- (instancetype )init
4144{
4245 if (self = [super init ]) {
43- [[RCTKeyWindowValuesProxy sharedInstance ] startObservingWindowSizeIfNecessary ];
46+ _applicationWindow = RCTKeyWindow ();
47+ [_applicationWindow addObserver: self forKeyPath: kFrameKeyPath options: NSKeyValueObservingOptionNew context: nil ];
4448 }
4549 return self;
4650}
4751
52+ - (void )observeValueForKeyPath : (NSString *)keyPath
53+ ofObject : (id )object
54+ change : (NSDictionary *)change
55+ context : (void *)context
56+ {
57+ if ([keyPath isEqualToString: kFrameKeyPath ]) {
58+ [self interfaceFrameDidChange ];
59+ [[NSNotificationCenter defaultCenter ] postNotificationName: RCTWindowFrameDidChangeNotification object: self ];
60+ }
61+ }
62+
4863+ (BOOL )requiresMainQueueSetup
4964{
50- return NO ;
65+ return YES ;
5166}
5267
5368- (dispatch_queue_t )methodQueue
@@ -81,7 +96,7 @@ - (void)initialize
8196
8297#if TARGET_OS_IOS
8398
84- _currentInterfaceOrientation = [RCTKeyWindowValuesProxy sharedInstance ]. currentInterfaceOrientation ;
99+ _currentInterfaceOrientation = RCTKeyWindow (). windowScene . interfaceOrientation ;
85100
86101 [[NSNotificationCenter defaultCenter ] addObserver: self
87102 selector: @selector (interfaceFrameDidChange )
@@ -98,6 +113,15 @@ - (void)initialize
98113 selector: @selector (invalidate )
99114 name: RCTBridgeWillInvalidateModulesNotification
100115 object: nil ];
116+
117+ _constants = @{
118+ @" Dimensions" : [self _exportedDimensions ],
119+ // Note:
120+ // This prop is deprecated and will be removed in a future release.
121+ // Please use this only for a quick and temporary solution.
122+ // Use <SafeAreaView> instead.
123+ @" isIPhoneX_deprecated" : @(RCTIsIPhoneNotched ()),
124+ };
101125}
102126
103127- (void )invalidate
@@ -120,6 +144,8 @@ - (void)_cleanupObservers
120144
121145 [[NSNotificationCenter defaultCenter ] removeObserver: self name: RCTBridgeWillInvalidateModulesNotification object: nil ];
122146
147+ [_applicationWindow removeObserver: self forKeyPath: kFrameKeyPath ];
148+
123149#if TARGET_OS_IOS
124150 [[NSNotificationCenter defaultCenter ] removeObserver: self name: UIDeviceOrientationDidChangeNotification object: nil ];
125151#endif
@@ -132,8 +158,13 @@ static BOOL RCTIsIPhoneNotched()
132158
133159#if TARGET_OS_IOS
134160 dispatch_once (&onceToken, ^{
161+ RCTAssertMainQueue ();
162+
135163 // 20pt is the top safeArea value in non-notched devices
136- isIPhoneNotched = [RCTWindowSafeAreaProxy sharedInstance ].currentSafeAreaInsets .top > 20 ;
164+ UIWindow *keyWindow = RCTKeyWindow ();
165+ if (keyWindow) {
166+ isIPhoneNotched = keyWindow.safeAreaInsets .top > 20 ;
167+ }
137168 });
138169#endif
139170
@@ -142,11 +173,13 @@ static BOOL RCTIsIPhoneNotched()
142173
143174static NSDictionary *RCTExportedDimensions (CGFloat fontScale)
144175{
176+ RCTAssertMainQueue ();
145177 UIScreen *mainScreen = UIScreen.mainScreen ;
146178 CGSize screenSize = mainScreen.bounds .size ;
179+ UIView *mainWindow = RCTKeyWindow ();
147180
148181 // We fallback to screen size if a key window is not found.
149- CGSize windowSize = [RCTKeyWindowValuesProxy sharedInstance ]. windowSize ;
182+ CGSize windowSize = mainWindow ? mainWindow. bounds . size : screenSize ;
150183
151184 NSDictionary <NSString *, NSNumber *> *dimsWindow = @{
152185 @" width" : @(windowSize.width ),
@@ -170,7 +203,10 @@ - (NSDictionary *)_exportedDimensions
170203 RCTAssert (_moduleRegistry, @" Failed to get exported dimensions: RCTModuleRegistry is nil" );
171204 RCTAccessibilityManager *accessibilityManager =
172205 (RCTAccessibilityManager *)[_moduleRegistry moduleForName: " AccessibilityManager" ];
173- RCTAssert (accessibilityManager, @" Failed to get exported dimensions: AccessibilityManager is nil" );
206+ // TOOD(T225745315): For some reason, accessibilityManager is nil in some cases.
207+ // We default the fontScale to 1.0 in this case. This should be okay: if we assume
208+ // that accessibilityManager will eventually become available, js will eventually
209+ // be updated with the correct fontScale.
174210 CGFloat fontScale = accessibilityManager ? accessibilityManager.multiplier : 1.0 ;
175211 return RCTExportedDimensions (fontScale);
176212}
@@ -182,14 +218,7 @@ - (NSDictionary *)_exportedDimensions
182218
183219- (NSDictionary <NSString *, id> *)getConstants
184220{
185- return @{
186- @" Dimensions" : [self _exportedDimensions ],
187- // Note:
188- // This prop is deprecated and will be removed in a future release.
189- // Please use this only for a quick and temporary solution.
190- // Use <SafeAreaView> instead.
191- @" isIPhoneX_deprecated" : @(RCTIsIPhoneNotched ()),
192- };
221+ return _constants;
193222}
194223
195224- (void )didReceiveNewContentSizeMultiplier
@@ -209,10 +238,11 @@ - (void)didReceiveNewContentSizeMultiplier
209238- (void )interfaceOrientationDidChange
210239{
211240#if TARGET_OS_IOS && !TARGET_OS_MACCATALYST
212- UIWindow *keyWindow = RCTKeyWindow ();
213- UIInterfaceOrientation nextOrientation = keyWindow .windowScene .interfaceOrientation ;
241+ UIApplication *application = RCTSharedApplication ();
242+ UIInterfaceOrientation nextOrientation = RCTKeyWindow () .windowScene .interfaceOrientation ;
214243
215- BOOL isRunningInFullScreen = CGRectEqualToRect (keyWindow.frame , keyWindow.screen .bounds );
244+ BOOL isRunningInFullScreen =
245+ CGRectEqualToRect (application.delegate .window .frame , application.delegate .window .screen .bounds );
216246 // We are catching here two situations for multitasking view:
217247 // a) The app is in Split View and the container gets resized -> !isRunningInFullScreen
218248 // b) The app changes to/from fullscreen example: App runs in slide over mode and goes into fullscreen->
@@ -275,4 +305,4 @@ - (void)_interfaceFrameDidChange
275305Class RCTDeviceInfoCls (void )
276306{
277307 return RCTDeviceInfo.class ;
278- }
308+ }
0 commit comments