Hook On to Exit Event of Application and Show an Alert

I need to show an alert box when the user quits the application by clicking on the `x` button.How can I hook on to the exit event of the application and show an alert or view controller via a segue



    performSegue(withIdentifier: "segue", sender: nil)



Please advice..

Accepted Reply

You don't use windowShouldClose correctly : it returns a Bool.


So write as I proposed (may need to adapt the modalResponses cases :


    func windowShouldClose(sender: AnyObject) -> Bool {
   
            let alert = NSAlert()
            alert.messageText = "Some alert."
            alert.informativeText = "Do something before closing."
            alert.addButton(withTitle: "Quit")
            alert.addButton(withTitle: "Activate License")
            alert.alertStyle = .WarningAlertStyle 
            let modalResponse = alert.runModal()
            if (modalResponse == NSAlertFirstButtonReturn)   { 
                   NSApplication.shared().terminate(self)
             }  else if (modalResponse==NSAlertSecondButtonReturn)   { 
                   activate(self)  // I'm not sure what you want to get here : what do you activate
             }
            return (modalResponse == NSAlertFirstButtonReturn)     // This is important for the window not to close if NSAlertSecondButtonReturn
    }

Replies

which "x" button is this ?


Do you confirm it is for OSX ?

Its the Close button on the Top Left corner for OSX Application window.

How does closing by clicking the red button quit the application ? It just close the window.

May be I do not understand exactly what you mean.


However, you should put the alert in the windowShouldClose, such as


    func windowShouldClose(sender: AnyObject) -> Bool {
      
            let alert = NSAlert()
            alert.messageText = "Some alert."
            alert.informativeText = "Do something before closing."
            alert.addButtonWithTitle("OK")
            alert.addButtonWithTitle("Close anyway")
            alert.alertStyle = .WarningAlertStyle
            let modalResponse = alert.runModal()
            return (modalResponse == NSAlertSecondButtonReturn) 
    }


This let you close or stop closing

How does closing by clicking the red button quit the application ?

Perhaps they’ve implemented

applicationShouldTerminateAfterLastWindowClosed(_:)
to return true?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I did not know about this. Likely.


Even though, the windowShouldClose should make it.

Thanks for your answer.Sorry im new to OSX and SWIFT.In windows when the `X` is clicked the Application closes.

I thought the application did not close as i was debugging in XCODE.


What i want to achieve is show a Trial notification to the user.When he/she tries to quit the application.


ie:You are using a trial version of my product ........

Your function does not work when i add Bool Return Type .


This thing works


class ViewController: NSViewController, NSWindowDelegate {
    / 
    override func viewDidAppear() {
        self.view.window?.delegate = self
    }
    func windowShouldClose(_ sender: Any) {
       let alert = NSAlert()
        alert.messageText = "Some alert."
        alert.informativeText = "Do something before closing."
        alert.addButton(withTitle: "Quit")
        alert.addButton(withTitle: "Activate License")
        let modalResponse = alert.runModal()
        if (modalResponse == NSAlertFirstButtonReturn)
        {
            NSApplication.shared().terminate(self)
        }
        else if(modalResponse==NSAlertSecondButtonReturn)
        {
            activate(self)
        }
    }
}


But after activate(self) is called .. the application quits (the Dock Icon stays there).I want the application window to stay there when the user Chooses Activate option .. How can i achieve this?

You don't use windowShouldClose correctly : it returns a Bool.


So write as I proposed (may need to adapt the modalResponses cases :


    func windowShouldClose(sender: AnyObject) -> Bool {
   
            let alert = NSAlert()
            alert.messageText = "Some alert."
            alert.informativeText = "Do something before closing."
            alert.addButton(withTitle: "Quit")
            alert.addButton(withTitle: "Activate License")
            alert.alertStyle = .WarningAlertStyle 
            let modalResponse = alert.runModal()
            if (modalResponse == NSAlertFirstButtonReturn)   { 
                   NSApplication.shared().terminate(self)
             }  else if (modalResponse==NSAlertSecondButtonReturn)   { 
                   activate(self)  // I'm not sure what you want to get here : what do you activate
             }
            return (modalResponse == NSAlertFirstButtonReturn)     // This is important for the window not to close if NSAlertSecondButtonReturn
    }

Thanks.`activate(self)` calls a segue to show a view controller as a sheet.Once this is shown, the app closes (or goes to the dock)

;I don't need it to close.

Plus when i add your Code with the Bool Return Type.No alert is shown,the app window just closes.

Well, I am not sure to understand where you click exactly, on which part of which object.

Let's get back to the technical issues here.


— On macOS, there is a difference between closing a window and quitting (terminating) an app.


— In general, there are single-window apps (which either have precisely one window, or have one main window, and other windows are auxiliary), and multiple-window apps (which have one window per document or task, or something similar). It is usual for single-window apps to quit automatically when their (main) window is closed. It is not usual for multiple-window apps to do that.


— If your app is a single-window app, then override the NSApplicationDelegate method "applicationShouldTerminateAfterLastWindowClosed" that Quinn referred to to get the automatic-termination behavior.


— If you want to put up an alert when the app is about to terminate, then you can override the NSApplicationDelegate method "applicationShouldTerminate" to cause the alert to be displayed, and return the ".terminateLater" result to give your alert a chance to be handled. You would use the NSAlert class for such an alert, typically.


— If you want to do something more complicated than put up an alert (such as segue to a different window in a storyboard), you likely can't use the above technique. Instead, you would likely need to intervene when windows are closed (as Claude was suggesting), but you're going to have to figure out the logic of terminating or not terminating yourself. I wouldn't recommend this approach if you can use the above technique instead. (For example, if you want to tell the user how long is left till the end of a trial period, a NSAlert should be all you need.)

The close 'X' icon on top of the window.