Search code examples
iosobjective-ccrash-reportsvisual-studio-app-center

App Center crash report confirmation disappears after app finish launching


I'm implementing App Center SDK in Objective-C application, and I need to implement confirmation of crash report sending. Solution provided by Microsoft in their guide generally works (https://learn.microsoft.com/en-us/appcenter/sdk/crashes/ios), but in my application, after application:didFinishLaunchingWithOptions: method finishes executing, home view appears (during launching, loading screen is shown), which shuts down alert with confirmation.

I've tried to use performSelectorOnMainThread:withObject:waitUntilDone with YES on waitUntilDone - it doesn't work.

If I try to implement this alert in another method (not in application:didFinishLaunchingWithOptions:) - alert just doesn't appear.

UI blocking with "while" loop (waiting for answer) leads to crash.

Here is default solution from Microsoft, which doesn't work as I want.

[MSCrashes setUserConfirmationHandler:(^(NSArray<MSErrorReport *> *errorReports) {
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"crash" message:@"message" preferredStyle:UIAlertControllerStyleAlert];                                                    

    UIAlertAction* sendAction = [UIAlertAction actionWithTitle:@"Send"
                                                         style:UIAlertActionStyleDefault
                                                       handler:^(UIAlertAction *action) {
                                                           [MSCrashes notifyWithUserConfirmation:MSUserConfirmationSend];
                                                       }];

    [alertController addAction:sendAction];
    alertController.preferredAction = sendAction;

    [alertController addAction:[UIAlertAction actionWithTitle:@"Always send"
                                                        style:UIAlertActionStyleDefault
                                                      handler:^(UIAlertAction *action) {
                                                          [MSCrashes notifyWithUserConfirmation:MSUserConfirmationAlways];
                                                      }]];

    [alertController addAction:[UIAlertAction actionWithTitle:@"Don't send"
                                                        style:UIAlertActionStyleDefault
                                                      handler:^(UIAlertAction *action) {
                                                          [MSCrashes notifyWithUserConfirmation:MSUserConfirmationDontSend];
                                                      }]];

    [self.window.rootViewController presentViewController:alertController animated:YES completion:nil];
    return YES;
})]

I expect that users will be able to think as much time as they want before sending report or not, but alert disappears after app finishes launching and new (app home) view appears.

Didn't anyone face this problem? And how did you solve it?


Solution

  • Solved.

    I hope this will help to someone.

    [MSCrashes setUserConfirmationHandler:(^(NSArray<MSErrorReport *> *errorReports) {
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"crash"
                                                                                 message:@"message"
                                                                          preferredStyle:UIAlertControllerStyleAlert];
    
        UIAlertAction* sendAction = [UIAlertAction actionWithTitle:@"Send"
                                                             style:UIAlertActionStyleDefault
                                                           handler:^(UIAlertAction *action) {
                                                               [MSCrashes notifyWithUserConfirmation:MSUserConfirmationSend];
                                                               [self.window makeKeyAndVisible];
                                                           }];
    
        [alertController addAction:sendAction];
        alertController.preferredAction = sendAction;
    
        [alertController addAction:[UIAlertAction actionWithTitle:@"Always send"
                                                            style:UIAlertActionStyleDefault
                                                          handler:^(UIAlertAction *action) {
                                                              [MSCrashes notifyWithUserConfirmation:MSUserConfirmationAlways];
                                                              [self.window makeKeyAndVisible];
                                                          }]];
    
        [alertController addAction:[UIAlertAction actionWithTitle:@"Don't send"
                                                            style:UIAlertActionStyleDefault
                                                          handler:^(UIAlertAction *action) {
                                                              [MSCrashes notifyWithUserConfirmation:MSUserConfirmationDontSend];
                                                              [self.window makeKeyAndVisible];
                                                          }]];
    
        self.alertWindowForCrashReport = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
        self.alertWindowForCrashReport.rootViewController = [[UIViewController alloc] init];
        [self.alertWindowForCrashReport makeKeyAndVisible];
        [self.alertWindowForCrashReport.rootViewController presentViewController:alertController animated:YES completion:nil];
    
        return YES; // Return YES if the SDK should await user confirmation, otherwise NO.
    })];
    

    Now I'm creating alert in new window, send [self.alertWindowForCrashReport makeKeyAndVisible] to this new window for alert, and then in every action handler send [self.window makeKeyAndVisible] to main window.