Skip to content

Commit

Permalink
Add and use reloadWithReason to iOS
Browse files Browse the repository at this point in the history
Summary:
This diff adds a new reloading method reloadWithReason that allows callers to provide a reason for why a reload was requested.

This reason is useful for understanding why users are reloading, and why Fast Refresh is bailing out to a full reload. I also updated the places we reload with the reasons listed below.

**Standard native reasons:**
- Redbox
- Command
- Global hotkey
- Profiling controls
- Dev menu - reload
- Dev menu - reset to default
- Dev menu - apply changes

**From JavaScript (added in a later diff):**
- Fast Refresh - Unrecoverable
- Fast Refresh - No root boundary
- Fast Refresh - Invalidated boundary
- Fast Refresh - Invalidated root boundary

**Misc reasons and fallback for when a reason is unavailable:**
- Unknown from JS
- Uncategorized from JS
- Unknown from bridge
- Unknown from cxx bridge
- Requested from bridge
- Custom executor class reset

Reviewed By: cpojer

Differential Revision: D17499339

fbshipit-source-id: 12a21ffa05708c9b921d93911f190cdffc5c78d5
  • Loading branch information
rickhanlonii authored and facebook-github-bot committed Sep 30, 2019
1 parent 59b96fe commit 2ccc8fb
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 16 deletions.
9 changes: 7 additions & 2 deletions React/Base/RCTBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,12 +254,17 @@ RCT_EXTERN void RCTEnableTurboModule(BOOL enabled);
/**
* Reload the bundle and reset executor & modules. Safe to call from any thread.
*/
- (void)reload;
- (void)reload __deprecated_msg("Call reloadWithReason instead");

/**
* Reload the bundle and reset executor & modules. Safe to call from any thread.
*/
- (void)reloadWithReason:(NSString *)reason;

/**
* Inform the bridge, and anything subscribing to it, that it should reload.
*/
- (void)requestReload __deprecated_msg("Call reload instead");
- (void)requestReload __deprecated_msg("Call reloadWithReason instead");

/**
* Says whether bridge has started receiving calls from javascript.
Expand Down
14 changes: 11 additions & 3 deletions React/Base/RCTBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ - (void)setRCTTurboModuleLookupDelegate:(id<RCTTurboModuleLookupDelegate>)turboM

- (void)didReceiveReloadCommand
{
[self reload];
[self reloadWithReason:@"Command"];
}

- (NSArray<Class> *)moduleClasses
Expand Down Expand Up @@ -290,14 +290,22 @@ - (BOOL)moduleIsInitialized:(Class)moduleClass
return [self.batchedBridge moduleIsInitialized:moduleClass];
}

/**
* Legacy reload, please use reloadWithReason and provide a reason for stats.
*/
- (void)reload
{
[self reloadWithReason:@"Unknown from bridge"];
}

- (void)reloadWithReason:(NSString *)reason
{
#if RCT_ENABLE_INSPECTOR && !TARGET_OS_UIKITFORMAC
// Disable debugger to resume the JsVM & avoid thread locks while reloading
[RCTInspectorDevServerHelper disableDebugger];
#endif

[[NSNotificationCenter defaultCenter] postNotificationName:RCTBridgeWillReloadNotification object:self];
[[NSNotificationCenter defaultCenter] postNotificationName:RCTBridgeWillReloadNotification object:self userInfo:@{@"reason": reason} ];

/**
* Any thread
Expand All @@ -314,7 +322,7 @@ - (void)reload

- (void)requestReload
{
[self reload];
[self reloadWithReason:@"Requested from bridge"];
}

- (Class)bridgeClass
Expand Down
12 changes: 10 additions & 2 deletions React/CxxBridge/RCTCxxBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ - (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoa
}
return moduleData.instance;
}

static NSSet<NSString *> *ignoredModuleLoadFailures = [NSSet setWithArray: @[@"UIManager"]];

// Module may not be loaded yet, so attempt to force load it here.
Expand Down Expand Up @@ -1009,7 +1009,15 @@ - (void)reload
if (!_valid) {
RCTLogWarn(@"Attempting to reload bridge before it's valid: %@. Try restarting the development server if connected.", self);
}
[_parentBridge reload];
[_parentBridge reloadWithReason:@"Unknown from cxx bridge"];
}

- (void)reloadWithReason:(NSString *)reason
{
if (!_valid) {
RCTLogWarn(@"Attempting to reload bridge before it's valid: %@. Try restarting the development server if connected.", self);
}
[_parentBridge reloadWithReason:reason];
}

- (Class)executorClass
Expand Down
8 changes: 4 additions & 4 deletions React/DevSupport/RCTDevMenu.m
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ - (void)setDefaultJSBundle
[[RCTBundleURLProvider sharedSettings] resetToDefaults];
self->_bridge.bundleURL = [[RCTBundleURLProvider sharedSettings] jsBundleURLForFallbackResource:nil
fallbackExtension:nil];
[self->_bridge reload];
[self->_bridge reloadWithReason:@"Dev menu - reset to default"];
}

- (NSArray<RCTDevMenuItem *> *)_menuItemsToPresent
Expand All @@ -214,7 +214,7 @@ - (void)setDefaultJSBundle

[items addObject:[RCTDevMenuItem buttonItemWithTitle:@"Reload"
handler:^{
[bridge reload];
[bridge reloadWithReason:@"Dev menu - reload"];
}]];

if (!devSettings.isProfilingEnabled) {
Expand Down Expand Up @@ -373,7 +373,7 @@ - (void)setDefaultJSBundle
fallbackResource:nil]
: [strongBridge.delegate sourceURLForBridge:strongBridge];
strongBridge.bundleURL = bundleURL;
[strongBridge reload];
[strongBridge reloadWithReason:@"Dev menu - apply changes"];
}
}]];
[alertController addAction:[UIAlertAction actionWithTitle:@"Reset to Default"
Expand Down Expand Up @@ -455,7 +455,7 @@ - (BOOL)shakeToShow
RCT_EXPORT_METHOD(reload)
{
WARN_DEPRECATED_DEV_MENU_EXPORT();
[_bridge reload];
[_bridge reloadWithReason:@"Unknown from JS"];
}

RCT_EXPORT_METHOD(debugRemotely : (BOOL)enableDebug)
Expand Down
15 changes: 12 additions & 3 deletions React/Modules/RCTDevSettings.mm
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ - (void)setBridge:(RCTBridge *)bridge
if (params != (id)kCFNull && [params[@"debug"] boolValue]) {
weakBridge.executorClass = objc_lookUpClass("RCTWebSocketExecutor");
}
[weakBridge reload];
[weakBridge reloadWithReason:@"Global hotkey"];
}
queue:dispatch_get_main_queue()
forMethod:@"reload"];
Expand Down Expand Up @@ -236,7 +236,13 @@ - (BOOL)isHotLoadingAvailable

RCT_EXPORT_METHOD(reload)
{
[self.bridge reload];
[self.bridge reloadWithReason:@"Unknown From JS"];
}

RCT_EXPORT_METHOD(reloadWithReason : (NSString *) reason)
{
[self.bridge reloadWithReason:reason];

}

RCT_EXPORT_METHOD(setIsShakeToShowDevMenuEnabled : (BOOL)enabled)
Expand Down Expand Up @@ -369,7 +375,7 @@ - (void)setExecutorClass:(Class)executorClass
}

self.bridge.executorClass = executorClass;
[self.bridge reload];
[self.bridge reloadWithReason:@"Custom executor class reset"];
}
}

Expand Down Expand Up @@ -442,6 +448,9 @@ - (id)settingForKey:(NSString *)key
- (void)reload
{
}
- (void)reloadWithReason
{
}
- (void)toggleElementInspector
{
}
Expand Down
2 changes: 1 addition & 1 deletion React/Modules/RCTRedBox.m
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ - (void)reloadFromRedBoxWindow:(__unused RCTRedBoxWindow *)redBoxWindow
if (_overrideReloadAction) {
_overrideReloadAction();
} else {
[_bridge reload];
[_bridge reloadWithReason:@"Redbox"];
}
[self dismiss];
}
Expand Down
2 changes: 1 addition & 1 deletion React/Profiler/RCTProfile.m
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ + (void)vsync:(CADisplayLink *)displayLink

+ (void)reload
{
[RCTProfilingBridge() reload];
[RCTProfilingBridge() reloadWithReason:@"Profiling controls"];
}

+ (void)toggle:(UIButton *)target
Expand Down

0 comments on commit 2ccc8fb

Please sign in to comment.