From ae7bbe06c9a4e47e1aa6cfa5cca7f6aa5a8ff83b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwas=CC=81niewski?= Date: Mon, 3 Mar 2025 03:47:46 -0800 Subject: [PATCH] fix: make React Native work without AppDelegate window property (#49748) Summary: This PR makes React Native not relying on the `window` property in AppDelegate. When running in SwiftUI lifecycle mode / SceneDelegate mode there is window property on AppDelegate. This PR fixes crashes that happen because RN asserts window property is there. ## Changelog: [IOS] [FIXED] - make React Native work without AppDelegate window property Pull Request resolved: https://github.com/facebook/react-native/pull/49748 Test Plan: CI Green Reviewed By: javache Differential Revision: D70389691 Pulled By: cipolleschi fbshipit-source-id: fe39f123b47014ba91a080239ccd298192c92a6a --- .../React/Base/UIKitProxies/RCTWindowSafeAreaProxy.mm | 4 ++-- packages/react-native/React/CoreModules/RCTDeviceInfo.mm | 7 +++---- packages/react-native/React/CoreModules/RCTRedBox.mm | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/react-native/React/Base/UIKitProxies/RCTWindowSafeAreaProxy.mm b/packages/react-native/React/Base/UIKitProxies/RCTWindowSafeAreaProxy.mm index 057edaa6713..440514a5088 100644 --- a/packages/react-native/React/Base/UIKitProxies/RCTWindowSafeAreaProxy.mm +++ b/packages/react-native/React/Base/UIKitProxies/RCTWindowSafeAreaProxy.mm @@ -34,7 +34,7 @@ std::lock_guard lock(_mutex); if (!_isObserving) { _isObserving = YES; - _currentSafeAreaInsets = [UIApplication sharedApplication].delegate.window.safeAreaInsets; + _currentSafeAreaInsets = RCTKeyWindow().safeAreaInsets; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_interfaceFrameDidChange) name:RCTUserInterfaceStyleDidChangeNotification @@ -64,7 +64,7 @@ - (void)_interfaceFrameDidChange { std::lock_guard lock(_mutex); - _currentSafeAreaInsets = [UIApplication sharedApplication].delegate.window.safeAreaInsets; + _currentSafeAreaInsets = RCTKeyWindow().safeAreaInsets; } @end diff --git a/packages/react-native/React/CoreModules/RCTDeviceInfo.mm b/packages/react-native/React/CoreModules/RCTDeviceInfo.mm index 8761904c55b..6b4fcef8522 100644 --- a/packages/react-native/React/CoreModules/RCTDeviceInfo.mm +++ b/packages/react-native/React/CoreModules/RCTDeviceInfo.mm @@ -209,11 +209,10 @@ static NSDictionary *RCTExportedDimensions(CGFloat fontScale) - (void)interfaceOrientationDidChange { #if TARGET_OS_IOS && !TARGET_OS_MACCATALYST - UIApplication *application = RCTSharedApplication(); - UIInterfaceOrientation nextOrientation = RCTKeyWindow().windowScene.interfaceOrientation; + UIWindow *keyWindow = RCTKeyWindow(); + UIInterfaceOrientation nextOrientation = keyWindow.windowScene.interfaceOrientation; - BOOL isRunningInFullScreen = - CGRectEqualToRect(application.delegate.window.frame, application.delegate.window.screen.bounds); + BOOL isRunningInFullScreen = CGRectEqualToRect(keyWindow.frame, keyWindow.screen.bounds); // We are catching here two situations for multitasking view: // a) The app is in Split View and the container gets resized -> !isRunningInFullScreen // b) The app changes to/from fullscreen example: App runs in slide over mode and goes into fullscreen-> diff --git a/packages/react-native/React/CoreModules/RCTRedBox.mm b/packages/react-native/React/CoreModules/RCTRedBox.mm index d427c053cda..fb057b96921 100644 --- a/packages/react-native/React/CoreModules/RCTRedBox.mm +++ b/packages/react-native/React/CoreModules/RCTRedBox.mm @@ -222,7 +222,7 @@ #if TARGET_OS_MACCATALYST return 0; #else - return RCTSharedApplication().delegate.window.safeAreaInsets.bottom; + return RCTKeyWindow().safeAreaInsets.bottom; #endif }