My app at launch time prompts the user with a template chooser, this works fine on Snow Leopard but on Lion the window never appears maybe due to restoration behaviour.
My app is NSDocument based and I use NSDocumentController to open the window on newDocument:(id)sender
Now on Lion no application delegate related to "untitiled" is called so I don't understard how to make it working
I think XCode 4 is NSDocument based and it shows the Startup Panel, how it does?
Another smart XCode Startup Panel's behaviour consists to show the panel only when no other windows are restored, again how this is implemented in Lion?
You're right to suspect the new restorable state behavior. The app may never be asked to create a new, empty document when relaunched/resumed. This is stated in the release notes:
As part of the restorable windows feature, the application delegate
may not be asked to create an Untitled window at launch in some
circumstances. This was found to cause crashes in certain apps, so
these apps will maintain 10.6 behavior of more often opening Untitled
windows. When these apps are recompiled on 10.7, they will acquire the
10.7 behavior. For maximum compatibility, do not depend on being asked
to create an Untitled window at launch.
They don't mention an alternative, and the document-based app documentation does not appear to have been updated yet with restorable state information.
As to your approach, you could change so that the template chooser is shown as a sheet on a new, empty doc window (like Pages or Instruments, for example). The document's contents are set when the template sheet is completed. This way, each new document shows its template sheet but this only happens if the user requests a new document, rather than relying on a fresh app launch (which you're no longer meant to do).
Related
I have an app that needs to open and track multiple windows. New windows are created in response to a File > New Window command, and are created programmatically (no storyboards or XIBs).
There are no documents involved, so I don't want any of the file actions, modified state tracking, or other document-related features that come with a Document-based application from Xcode. I do want the ability to cascade new windows, and to remember the size and position of all open windows so they can be restored when the app launches.
Tracking the open windows is easy enough and there are plenty of examples out there. I can set an autosave name, but that only seems to work on the first window that gets created. NSWindowController.shouldCascadeWindows only seems to work with Document-based apps.
Do I have to implement cascading and geometry persistence myself, or is there some way to hook into those features? Thanks!
On Mac it is usual that there is a "hidden" main window.
The usual example is "Text Edit". When you open a file you with you don't see a "main frame". Instead every single file will be opened in its own "Text Edit" instance. This is OSX way of emulating the so-called MDI interface.
However, there is an exception. If you open Xcode and open the project there, you can click on the file and it will be open inside the main Xcode window. And if you double click the file it will be opened in its own independent editor window, keeping the main Xcode window visible.
My question would be: do I need to do anything special in order to make my program behave like an Xcode? Should I use different class for the main frame or maybe react differently on the opening document event?
Any hints/pointers where to look or even to the official Apple documentation would be helpful.
The TextEdit behavior you're describing is much more like “SDI” than “MDI”, and the terms “SDI” and “MDI” weren't even needed until Microsoft invented MDI long after Xerox invented the SDI-type interface of which macOS is a derivative.
Anyway, I think you are misunderstanding Xcode's behavior. You seem to think “its own independent editor window” is a different kind of window than “the main Xcode window”. But in fact the new window is of the same kind as the old window, with some optional parts hidden. You can show those hidden parts and make the new window look exactly like the old window. Demo:
The ability to open multiple windows showing the same document (or, in Xcode's case, project) is a matter of software architecture. If you carefully design your app so that multiple windows can share a single model object graph, and can be notified and redraw themselves when the object graph changes, then you have an app that supports multiple windows showing the same document. If you want multiple kinds of windows showing the same document, nothing about Cocoa stands in your way. As a matter of fact, Xcode does have at least one other kind of window in which it shows some properties of a project:
That project settings sheet is really another window; macOS keeps it attached to the main window, but it is in fact an instance of NSWindow (or a subclass of NSWindow), no doubt with its own custom window controller that references the same project objects as the main window.
If you use the Cocoa NSDocument architecture, then a small amount of multi-window support is built-in: an NSDocument knows about its associated windows (via their window controllers). If you want to use the NSDocument architecture, you should read Document-Based App Programming Guide for Mac.
It is unclear what you are after. The traditional Mac UI has been one window per document - i.e. SDI with a single instance of the app running multiple windows - but there has always been the ability for any app to organise the content of that window as it sees fit, including showing multiple "documents" within one window - i.e MDI type UI.
Apps approach such "MDI" in different ways, e.g. some use panes (views) and others tabs. From macOS Sierra the standard NSWindow supports tabs, this system is (semi)automatic for standard document apps. Read Apple's NSWindow Automatic Window Tabbing section in the Sierra release notes for more details.
If you wish to use multiple panes - e.g. like Xcode - you just use views (NSView) and arrange them how you wish.
HTH
My document-based app immediately terminates the document upon cmd+w and it is not saved. How can I react to this and either prompt for saving the document or automatically save it?
Use the NSDocument method updateChangeCount(_:) to mark your document as edited, and Cocoa will take care of the rest!
Furthermore, if you use NSUndoManager for all changes, it updates the change count for you!
Most of the time, you should look for these kinds of "hooks" into existing Cocoa functionality, so that your app behaves exactly the same way as other OS X apps, and so that you inherit new features when new OS versions are released.
I'm creating a simple single-window app for OS X on Yosemite, targeting Mavericks, implemented in Swift. My storyboard is based on the default project one, so there is no custom window controller, just a ViewController.swift. When I close the window, the instance of that view controller is not released (code in deinit never executes), despite the fact that I have "Release When Closed" checked for the NSWindow object in the storyboard.
Furthermore, if I open it again (using a "show" segue), it appears to be a new instance of the window, not the existing, unreleased one. The upshot is that if I open and close the window multiple times, new instances of the view controller are created for each new window, but of course never released on close. Seems silly for the app to continue eating memory for each window.
How do I get windows to actually release themselves and related controllers and views on close?
Update: I discovered that, although "Release When Closed" is checked in IB, it’s false in viewWillAppear(). If I set it to true there, when I close the window, then open it again, when I close it again, I get an EXC_BAD_ACCESS error that just points at my AppDelegate class. :-(
if I open it again (using a "show" segue), it appears to be a new instance of the window, not the existing, unreleased one.
You need to set the presentation to Single, by default it's Multiple.
Make sure you click on the viewController button on the viewController on the storyboard:
enter image description here
Then update the presentation:
enter image description here
I just ran my app in the latest Xcode 6.2 beta, and the problem no longer exists there. Not sure I was remembering it properly, I ran the project in Xcode 6.1.1 and opening and closing the single window repeatedly continues to make the app grow in size.
So it looks like this is an issue that is fixed applications build by Xcode 6.2.
I'm dipping my feet into Cocoa for the first time.
Here's a simple question. OS X Lion supports Resuming of window state when an app is terminated and relaunched. Okay, good and fine.
But for document-based apps, can the same Resume feature also manage saving of window state when a document is closed and reopened later but without any quitting of the app? (In other words, can it manage each file's state persistently regardless of whether the app quits or not? Or do I have to manage it myself by saving the information in the documents' files?)
For instance, iWork '09 apps do do this sort of thing: if you close a saved document and reopen it, it will restore the window size, location, and scroller position. I don't know if it does this using Lion's Resume per se.
But, in contrast, OS X Lion's TextEdit restores windows when it is quit and restarted, but it does not remember window states when you close a document and reopen it. This makes me suspicious that using Resume without quitting might not be possible automatically (since maybe Pages keeps window states in its proprietary file format, but TextEdit doesn't since it uses plain text, RTF, HTML, etc. files).
I don't have access to the WWDC 2011 videos yet, and neither the OS X release notes, the OS X Application Programming Guide, nor the NSWindowRestoration API docs talk about this specifically.
So the question again: automatically remembering the state of a document window after closing and reopening it without quitting the app (like iWork does)...does Lion's Restore support this?
Thanks a lot!
But for document-based apps, can the same Resume feature also manage saving of window state when a document is closed and reopened later but without any quitting of the app? (In other words, can it manage each file's state persistently regardless of whether the app quits or not?
Not unassisted, no.
Or do I have to manage it myself by saving the information in the documents' files?)
Or somewhere else, yes.
My untested suggestion is to try using the window-restoration protocol yourself. When closing, send yourself encodeRestorableStateWithCoder:, then stash that data in your document (or wherever you want). When opening a document, if it has restorable state information, pass it to restoreStateWithCoder:.