Skip to content

Commit 485b3d8

Browse files
authored
Fix crash when displaying UIAlertController for a test on device message that errored (#4446)
* Use application delegate window to show test on device error alert, run on main thread * Refactor the display of the test on device error alert to use a window on the foregrounded scene * More descriptive variable name for the view controller used to present the error alert * Import UIKit at the top of FIRIAMDisplayExecutor.m * Early return in test on device error flow if there's no foregrounded scene * scripts/styles.sh
1 parent 40045b8 commit 485b3d8

File tree

1 file changed

+30
-4
lines changed

1 file changed

+30
-4
lines changed

Firebase/InAppMessaging/Flows/FIRIAMDisplayExecutor.m

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
#import <FirebaseCore/FIRLogger.h>
18+
#import <UIKit/UIKit.h>
1819

1920
#import "FIRCore+InAppMessaging.h"
2021
#import "FIRIAMActivityLogger.h"
@@ -41,6 +42,8 @@ @interface FIRIAMDisplayExecutor () <FIRInAppMessagingDisplayDelegate>
4142
@property(nonatomic) BOOL impressionRecorded;
4243
@property(nonatomic, nonnull, readonly) id<FIRIAMAnalyticsEventLogger> analyticsEventLogger;
4344
@property(nonatomic, nonnull, readonly) FIRIAMActionURLFollower *actionURLFollower;
45+
// Used for displaying the test on device message error alert.
46+
@property(nonatomic, strong) UIWindow *alertWindow;
4447
@end
4548

4649
@implementation FIRIAMDisplayExecutor {
@@ -307,14 +310,37 @@ - (void)displayMessageLoadError:(NSError *)error {
307310

308311
UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"OK"
309312
style:UIAlertActionStyleDefault
310-
handler:^(UIAlertAction *action){
313+
handler:^(UIAlertAction *action) {
314+
self.alertWindow.hidden = NO;
315+
self.alertWindow = nil;
311316
}];
312317

313318
[alert addAction:defaultAction];
314319

315-
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alert
316-
animated:YES
317-
completion:nil];
320+
dispatch_async(dispatch_get_main_queue(), ^{
321+
#if defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000
322+
if (@available(iOS 13.0, *)) {
323+
UIWindowScene *foregroundedScene = nil;
324+
for (UIWindowScene *connectedScene in [UIApplication sharedApplication].connectedScenes) {
325+
if (connectedScene.activationState == UISceneActivationStateForegroundActive) {
326+
foregroundedScene = connectedScene;
327+
break;
328+
}
329+
}
330+
331+
if (foregroundedScene == nil) {
332+
return;
333+
}
334+
self.alertWindow = [[UIWindow alloc] initWithWindowScene:foregroundedScene];
335+
}
336+
#else // defined(__IPHONE_13_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000
337+
self.alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
338+
#endif
339+
UIViewController *alertViewController = [[UIViewController alloc] init];
340+
self.alertWindow.rootViewController = alertViewController;
341+
self.alertWindow.hidden = NO;
342+
[alertViewController presentViewController:alert animated:YES completion:nil];
343+
});
318344
}
319345

320346
- (instancetype)initWithInAppMessaging:(FIRInAppMessaging *)inAppMessaging

0 commit comments

Comments
 (0)