Files
react-native/React/CoreModules/RCTLogBox.mm
T
Andrew Rahn 11644d78ed Hide the logbox window explicitly. New behavior in iOS SDK appears to… (#32435)
Summary:
Fixes  https://github.com/facebook/react-native/issues/32434: RCTLogBox window is orphaned, covering entire screen.

After this change, the logbox window once again is removed from the screen.

## Changelog

Some third-party SDKs may hold references to created UIWindow, UIViewController, or UIView objects. Doing so means that the current code's `hide` method that releases the reference to the UIWindow in LogBox will not cause the window to be dealloc'd, and thus instead it will remain on the screen. This change explicitly hides the LogBox window when the reference is released, so that even if some other SDK holds onto the window it will still be taken off the screen.

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->

[iOS] [Fixed] - 32434

Pull Request resolved: https://github.com/facebook/react-native/pull/32435

Test Plan:
1.     Use console.warn to generate a yellow warning message in log box.  Also install a third-party SDK that holds onto a reference to UIWindow -- for example the Facebook SDK, the Data Dog SDK, or any number of other SDKs that use `swizzling` to intercept calls like `viewDidAppear:`.
2.     click the log
3.     tap "dismiss"
4.     try to tap anywhere
5. Use Xcode view debugger to inspect the UI state

## Expected

The app still responds to the touch.
In Xcode, there is not an extra UIWindow covering the screen

Reviewed By: philIip

Differential Revision: D31794242

Pulled By: sshic

fbshipit-source-id: 28aa247b3ed3fd60b8e7c2ed7d0606cbf5c42408
2021-11-04 00:18:05 -07:00

129 lines
2.6 KiB
Plaintext

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTLogBox.h"
#import <FBReactNativeSpec/FBReactNativeSpec.h>
#import <React/RCTBridge.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTLog.h>
#import <React/RCTRedBoxSetEnabled.h>
#import <React/RCTSurface.h>
#import "CoreModulesPlugins.h"
#if RCT_DEV_MENU
@interface RCTLogBox () <NativeLogBoxSpec, RCTBridgeModule>
@end
@implementation RCTLogBox {
RCTLogBoxView *_view;
}
@synthesize bridge = _bridge;
RCT_EXPORT_MODULE()
+ (BOOL)requiresMainQueueSetup
{
return YES;
}
RCT_EXPORT_METHOD(show)
{
if (RCTRedBoxGetEnabled()) {
__weak RCTLogBox *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
__strong RCTLogBox *strongSelf = weakSelf;
if (!strongSelf) {
return;
}
if (strongSelf->_view) {
[strongSelf->_view show];
return;
}
if (strongSelf->_bridge) {
if (strongSelf->_bridge.valid) {
strongSelf->_view = [[RCTLogBoxView alloc] initWithFrame:[UIScreen mainScreen].bounds
bridge:strongSelf->_bridge];
[strongSelf->_view show];
}
} else {
NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:strongSelf, @"logbox", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"CreateLogBoxSurface" object:nil userInfo:userInfo];
}
});
}
}
RCT_EXPORT_METHOD(hide)
{
if (RCTRedBoxGetEnabled()) {
__weak RCTLogBox *weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
__strong RCTLogBox *strongSelf = weakSelf;
if (!strongSelf) {
return;
}
[strongSelf->_view setHidden: YES];
strongSelf->_view = nil;
});
}
}
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
(const facebook::react::ObjCTurboModule::InitParams &)params
{
return std::make_shared<facebook::react::NativeLogBoxSpecJSI>(params);
}
- (void)setRCTLogBoxView:(RCTLogBoxView *)view
{
self->_view = view;
}
@end
#else // Disabled
@interface RCTLogBox () <NativeLogBoxSpec>
@end
@implementation RCTLogBox
+ (NSString *)moduleName
{
return nil;
}
- (void)show
{
// noop
}
- (void)hide
{
// noop
}
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
(const facebook::react::ObjCTurboModule::InitParams &)params
{
return std::make_shared<facebook::react::NativeLogBoxSpecJSI>(params);
}
@end
#endif
Class RCTLogBoxCls(void)
{
return RCTLogBox.class;
}