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
This commit is contained in:
Oskar Kwaśniewski
2024-03-08 04:53:42 -08:00
committed by Facebook GitHub Bot
parent 642b4e5c2c
commit 4adef35e97
2 changed files with 44 additions and 7 deletions
@@ -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
@@ -28,6 +28,8 @@
#import <React/RCTLogBox.h>
#import <React/RCTModuleData.h>
#import <React/RCTPerformanceLogger.h>
#import <React/RCTRedBox.h>
#import <React/RCTReloadCommand.h>
#import <React/RCTSurfacePresenter.h>
#import <ReactCommon/RCTTurboModuleManager.h>
#import <ReactCommon/RuntimeExecutor.h>
@@ -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(<React/RCTDevLoadingViewProtocol.h>)
@@ -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