How to distinguish between different causes of app termination in Cocoa?
Asked Answered
B

1

7

I would like my application to ask for confirmation before quitting, except when it's being terminated by the system during shutdown or restart (because when OS X tries to apply security updates at midnight it gets stuck on the "Are you sure?" message box).

How can I find what initiated the termination? In [NSApp terminate:sender] the sender is always nil.

My first thought was to ask only when the "Quit" main menu item is activated, but the user can also terminate application from the Dock menu or by pressing Cmd+Q while holding Cmd+Tab, and I'd like to ask for confirmation in these cases as well.

Backfill answered 29/4, 2014 at 12:5 Comment(0)
S
3

You can get a notification when the system is about to power off, restart, or if the user just logs out. This is not an ordinary notification, but a workspace notification.

You can register for the notification like this:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    //...more code...

    self.powerOffRequestDate = [NSDate distantPast];
    NSNotificationCenter *wsnCenter = [[NSWorkspace sharedWorkspace] notificationCenter];
    [wsnCenter addObserver:self
                  selector:@selector(workspaceWillPowerOff:)
                      name:NSWorkspaceWillPowerOffNotification
                    object:nil];
}

in the notification handler, you should just save away the date:

- (void)workspaceWillPowerOff:(NSNotification *)notification
{
    self.powerOffRequestDate = [NSDate new];
}

Add

@property (atomic,strong,readwrite) NSDate *powerOffRequestDate;

to the appropriate place.

when your app is asked to terminate, you should get that date and check if the computer is about to shut off.

if([self.powerOffRequestDate timeIntervalSinceNow] > -60*5) {
    // shutdown immediately
} else {
    // ask user
}

I chose an intervall of 5minutes for the following edge case: The computer should power off, but another app cancels that. Your app is still running. 10min later, the user closes your app. In that case, the app should ask the user. This is a bit of a hack, but it's not a "crazy hack" I think...

Hope this helps.

Soupy answered 2/5, 2014 at 11:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.