SETUP:
I have developed a typical Cocoa Document-Based OS X Application.
My intention is to support Apple's User Interface Preservation feature to restore the open Documents/Windows from the prior run of the app.
This is supported by default in Document-based apps.
I am not overriding any of the related methods such as:
-[NSWindow isRestorable]
-[NSResponder encodeRestorableStateWithCoder:]
-[NSResponder decodeRestorableStateWithCoder:]
-[NSApplication restoreWindowWithIdentifier:state:completionHandler:]
-[NSDocumentController restoreWindowWithIdentifier:state:completionHandler:]
(Note: -[NSWindow isRestorable]
in my Document windows is already returning YES
by default. Presumably this is a feature of Document-Based apps)
I don't think I'm doing anything out of the ordinary in my app related to UI Preservation.
PROBLEM:
UI Preservation in my app is not working. But it's failing in a very odd way. As I run my app (either by building and running it in Xcode or by running a distribution build independently), the normal Saved Application State
folder is correctly created and populated with the correct application state information.
If I force quit my app (by abruptly stopping a running Xcode build or via the Dock Force Quit
menu item), and then restart my app, the UI Preservation feature works perfectly. The app finds the info stored in the Saved Application State
Folder and correctly restores open Documents/Windows from the prior run.
However, whenever I Quit my app normally, the entire Saved Application State
folder is deleted (I can see this happen in the Finder). So the next time I launch my app, there's no stored state to restore, and restoration fails.
I've tracked this Folder deletion down to happening sometime after -[NSApplication terminate:]
is called.
So I put a Symbolic Breakpoint on unlink()
, and sure enough, one-by-one some code in AppKit is purposely deleting the Saved Application State
folder and all of its contents.
Note the call to unlink()
from a queue called NSPersistentUI I/O
on the main thread from NSApplicationMain
. (This is not coming from my code obviously)
Why is AppKit destroying my Saved Application State
folder on normal app termination?
Is this normal?
How can I stop this?
We override the checkbox @indragie mentions for our sandbox app, since for new accounts that box is unchecked, and so critical state restoration functionality is lost.
The code is as easy as adding this to your main() routine:
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"NSQuitAlwaysKeepsWindows"]; // override stupid global preference, so our state restore works properly
Make sure that this box is unchecked in System Preferences > General:
When this box is checked, it disables state restoration system wide and results in the behaviour you described.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With