Hook On to Exit Event of Application and Show an Alert

Viewed 1567

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..

2 Answers

I know you want to use a segue to do this because they're just so convenient, but segues can't be done in a storyboard going from app delegate events like "applicationWillResignActive" (going to background) or "applicationWillBecomeActive" (becoming foreground again).

The correct way to do this would be via an alert. And you'd likely want to do this in applicationShouldTerminate, since you probably want to A) be able to abort quitting if you have a good reason not to quit just yet or B) give the user a choice whether or not to really quit.

Here's how it would look in swift 4:

var licenseWindowController : LicenseWindowController?

func dialogOKCancel(question: String, text: String) -> Bool {
    let alert = NSAlert()
    alert.messageText = question
    alert.informativeText = text
    alert.alertStyle = .warning
    alert.addButton(withTitle: "OK")
    alert.addButton(withTitle: "Cancel")
    return alert.runModal() == .alertFirstButtonReturn
}

func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {

    let answer = dialogOKCancel(question: "Ok?", text: "Should we really quit?")
    if answer == true
    {
        return .terminateNow
    } else {

func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {

    let answer = dialogOKCancel(question: "Ok?", text: "Should we really quit?")
    if answer == true
    {

        return .terminateNow

    } else {

        // to bring up a window from your storyboard...
        let mainStoryboard = NSStoryboard.init(name: NSStoryboard.Name(rawValue: "Main"), bundle: nil)
        self.licenseWindowController = mainStoryboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "LicenseWindowController")) as? LicenseWindowController
        if let actualLicenseWC = self.licenseWindowController
        {
            actualLicenseWC.showWindow(self)
        }

        return .terminateCancel
    }
}

Swift 3

var licenseWindowController : LicenseWindowController?

func dialogOKCancel(question: String, text: String) -> Bool {
    let alert = NSAlert()
    alert.messageText = question
    alert.informativeText = text
    alert.alertStyle = .warning
    alert.addButton(withTitle: "OK")
    alert.addButton(withTitle: "Cancel")
    return alert.runModal() == NSAlertFirstButtonReturn
}

func applicationShouldTerminate(_ sender: NSApplication) -> NSApplicationTerminateReply {

    let answer = dialogOKCancel(question: "Ok?", text: "Should we really quit?")
    if answer == true
    {
        return .terminateNow
    } else {
        let mainStoryboard = NSStoryboard.init(name: "Main", bundle: nil)
        self.licenseWindowController = mainStoryboard.instantiateController(withIdentifier: "LicenseWindowController") as? LicenseWindowController
        if let actualLicenseWC = self.licenseWindowController
        {
            actualLicenseWC.showWindow(self)
        }

        return .terminateCancel
    }
}

In your appdelegate you should be able to put your code into applicationWillTerminate and make the message appear there.

Edit: You would probably be better off using a modal alert instead of a segue.

Related