Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

On Quit Event? #111

Open
ghost opened this issue May 1, 2014 · 4 comments
Open

On Quit Event? #111

ghost opened this issue May 1, 2014 · 4 comments

Comments

@ghost
Copy link

ghost commented May 1, 2014

Is there a way to attach a function that is run just before app termination?

@jeff-h
Copy link
Member

jeff-h commented May 1, 2014

Hmm, I don't believe so. We need this.

I think it should be fairly straightforward; an implementation of applicationWillTerminate in AppDelegate.m should hopefully do the trick.

- (void) applicationWillTerminate:(NSNotification *)aNotification {
    NSLog(@"terminating");
}

My only concern is whether we can make it wait while we call the JavaScript.

@jeff-h
Copy link
Member

jeff-h commented May 1, 2014

Actually, as a stopgap you should be able to disconnect the default behaviour of the Quit menu command in Xcode interface builder, and then attach your own handler to the Quit menu item using the existing MacGap API. This won't intercept any other means of quitting your app though e.g. right-clicking the app icon in the dock.

@jeff-h
Copy link
Member

jeff-h commented May 17, 2014

I've looked into this more and the general consensus it that "Your code absolutely must be hardened against unexpected termination."

On other words, running something on quit is best avoided if at all possible, despite the apparent simplicity of the idea. There are lots of reasons for this e.g. you can't ever reliably handle force quits, other apps (e.g. the dock, or OS X itself) may send a quit command to your app, etc

Alternatives are:

  • save app state whenever it is changed (in MacGap that typically means either to LocalStorage or UserDefaults)
  • if cleanup is needed, do it on app launch instead
  • if a web service should know a client has quit, do it in a timeout on the server instead of sending a message on quit from the client

If none of the above are possible in your use case, can I ask what it is specifically you would like to do on quit?

@rawcreative
Copy link
Member

I've experimented with this a little bit and while triggering the events are easy to implement, they don't really do any good in the context of running JS code. The proper way to handle when the app should terminate is to use applicationShouldTerminate in AppDelegate and either pass back NSTerminateNow, or NSTerminateLater if you still need to do something e.g. save data, etc. When testing this though, if NSTerminateLater is used, the app can become unstable if it termination isn't allowed in a reasonable amount of time.

The only way that it appears this would work in MG's context is to rework the App API commands to use two separate commands, when needing to do cleanup/saves/etc. For example the primary command could be mac.app.quit(), which would trigger the shutdown events (and could delay termination using e.preventDefault() or some other method). If termination was in delayed and once cleanup is done, a command like mac.app.terminate() would need to be called to actually terminate. If termination wasn't delayed, the app would just terminate as normal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants