From 4adef35e97f31db466e536aa21d5eeec6ee34fc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwas=CC=81niewski?= Date: Fri, 8 Mar 2024 04:53:42 -0800 Subject: [PATCH] fix(iOS) [0.74]: RCTRedBox not appearing in Bridgeless when metro is not running (#43147) Summary: When testing out `0.74.0-rc0` I found that when the metro is not running we are not displaying RedBox which bumps users to start the packager and reload the app. It also fixes the case where users try to reload by clicking the "Reload" button on RedBox. ## Before https://github.com/facebook/react-native/assets/52801365/086c557f-ea1f-4a97-b4c7-df8a945cc7a0 ## After https://github.com/facebook/react-native/assets/52801365/9f8421b3-5e83-466f-8cdb-38f97981275d ## Changelog: [IOS] [FIXED] - RCTRedBox not appearing in Bridgeless when metro is not running Pull Request resolved: https://github.com/facebook/react-native/pull/43147 Test Plan: Build the app without metro running check if RedBox is shown Reviewed By: javache Differential Revision: D54632056 Pulled By: dmytrorykun fbshipit-source-id: fb6742898d3bd82545bfffd9175208e1a5984cb6 --- .../React/CoreModules/RCTRedBox.mm | 8 +++- .../platform/ios/ReactCommon/RCTInstance.mm | 43 ++++++++++++++++--- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/packages/react-native/React/CoreModules/RCTRedBox.mm b/packages/react-native/React/CoreModules/RCTRedBox.mm index 822e17ab570..15cf2f023aa 100644 --- a/packages/react-native/React/CoreModules/RCTRedBox.mm +++ b/packages/react-native/React/CoreModules/RCTRedBox.mm @@ -274,7 +274,13 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder) - (void)reload { - [_actionDelegate reloadFromRedBoxController:self]; + if (_actionDelegate != nil) { + [_actionDelegate reloadFromRedBoxController:self]; + } else { + // In bridgeless mode `RCTRedBox` gets deallocated, we need to notify listeners anyway. + RCTTriggerReloadCommandListeners(@"Redbox"); + [self dismiss]; + } } - (void)showExtraDataViewController diff --git a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm index 6b9f987123c..38f17f96129 100644 --- a/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm +++ b/packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.mm @@ -28,6 +28,8 @@ #import #import #import +#import +#import #import #import #import @@ -122,10 +124,17 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags) }]; } - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(_notifyEventDispatcherObserversOfEvent_DEPRECATED:) - name:@"RCTNotifyEventDispatcherObserversOfEvent_DEPRECATED" - object:nil]; + NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; + + [defaultCenter addObserver:self + selector:@selector(_notifyEventDispatcherObserversOfEvent_DEPRECATED:) + name:@"RCTNotifyEventDispatcherObserversOfEvent_DEPRECATED" + object:nil]; + + [defaultCenter addObserver:self + selector:@selector(didReceiveReloadCommand) + name:RCTTriggerReloadCommandNotification + object:nil]; [self _start]; } @@ -389,6 +398,24 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags) } } +- (void)handleBundleLoadingError:(NSError *)error +{ + if (!_valid) { + return; + } + + RCTRedBox *redBox = [_turboModuleManager moduleForName:"RedBox"]; + + RCTExecuteOnMainQueue(^{ + [[NSNotificationCenter defaultCenter] postNotificationName:RCTJavaScriptDidFailToLoadNotification + object:self + userInfo:@{@"error" : error}]; + [redBox showErrorMessage:[error localizedDescription]]; + + RCTFatal(error); + }); +} + - (void)_loadJSBundle:(NSURL *)sourceURL { #if RCT_DEV_MENU && __has_include() @@ -420,8 +447,7 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags) } if (error) { - // TODO(T91461138): Properly address bundle loading errors. - RCTLogError(@"RCTInstance: Error while loading bundle: %@", error); + [strongSelf handleBundleLoadingError:error]; [strongSelf invalidate]; return; } @@ -490,4 +516,9 @@ void RCTInstanceSetRuntimeDiagnosticFlags(NSString *flags) isFatal:errorMap.getBool(JSErrorHandlerKey::kIsFatal)]; } +- (void)didReceiveReloadCommand +{ + [self _loadJSBundle:[_bridgeModuleDecorator.bundleManager bundleURL]]; +} + @end