Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 273
Kornel Avatar asked Apr 29 '14 12:04

Kornel


People also ask

What is Cocoa (application) layer?

The Cocoa (Application) layer implements many features that are distinctive aspects of the OS X user experience. Users expect to find these features throughout the system, so it’s a good idea to support all the features that make sense in your app.

What is the difference between Cocoa Touch and AppKit?

The application framework for Mac systems makes use of AppKit, which is not present in Cocoa Touch. Instead, Touch is a combination of UIKit and Foundation. There are certain differences between the Foundation frameworks of Cocoa and Cocoa Touch as well.

What is the difference between API in cocoa and API in iOS?

API differences – The APIs used for making desktop and mobile applications are not entirely similar – and that brings us to this point. All the classes used in Cocoa have the NS prefix (i.e., NSTextField and NSWindow). Classes in Cocoa Touch, on the other hand, are prefixed by UI (i.e., UITextField and UIWindow).

What does it mean to terminate an app?

Hi SK123 terminating an app ends all processes associated with the app, handy if it gets itself in a knot, it does not remove the app, and the app can be restarted. uninstalling the app will remove it from the device.


1 Answers

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.

like image 149
Michael Avatar answered Oct 09 '22 23:10

Michael