From 46c77dc296dfab754356cd9346a01dae8d4869f4 Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Fri, 10 Apr 2020 13:49:16 -0700 Subject: [PATCH] Fix crash inside RCTRedBox when trying to present same UIViewController twice Summary: Calling `-[RCTRedBox showErrorMessage]` twice causes a crash We used `-[UIViewController isBeingPresented]` to tell whether view controller is already presented. But from the documentation: > A Boolean value indicating whether the view controller is being presented. Source: https://developer.apple.com/documentation/uikit/uiviewcontroller/2097564-beingpresented?language=objc# --- So this means that if you present it, wait until presentation animation is finished and then call `-[RCTRedBox showErrorMessage]` again, following exception will be thrown. ``` *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller .' ``` Changelog: Fix crash caused by presenting view controller twice from RCTRedBox Reviewed By: PeteTheHeat Differential Revision: D20946645 fbshipit-source-id: 763066e37db4e56efb0118b2e7867ad0724bae81 --- React/CoreModules/RCTRedBox.mm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/React/CoreModules/RCTRedBox.mm b/React/CoreModules/RCTRedBox.mm index 284b0ff0c87..93ddf21a255 100644 --- a/React/CoreModules/RCTRedBox.mm +++ b/React/CoreModules/RCTRedBox.mm @@ -235,10 +235,11 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder) // Remove ANSI color codes from the message NSString *messageWithoutAnsi = [self stripAnsi:message]; + BOOL isRootViewControllerPresented = self.rootViewController.presentingViewController != nil; // Show if this is a new message, or if we're updating the previous message - BOOL isNew = !self.rootViewController.isBeingPresented && !isUpdate; + BOOL isNew = !isRootViewControllerPresented && !isUpdate; BOOL isUpdateForSameMessage = !isNew && - (self.rootViewController.isBeingPresented && isUpdate && + (isRootViewControllerPresented && isUpdate && ((errorCookie == -1 && [_lastErrorMessage isEqualToString:messageWithoutAnsi]) || (errorCookie == _lastErrorCookie))); if (isNew || isUpdateForSameMessage) { @@ -250,7 +251,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)initWithCoder : (NSCoder *)aDecoder) [_stackTraceTableView reloadData]; - if (!self.rootViewController.isBeingPresented) { + if (!isRootViewControllerPresented) { [_stackTraceTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];