I have continued work on an app made by another. It looks in relevant parts identical to the standard NSDocument window-based app that you get when starting a new project (where the Window menu works like normal, ie. the NSDocument appears in the Window menu with the title Untitled).
But in this app, something seems to have happened to the Window menu or the app, that has somehow disconnected this automated behavior from the NSDocument.
Quite substantial work is needed to get this finished, submitted, and later rejected (by reviewers) app into a fresh project.
I'm looking to the experienced Mac app devs for:
What requirements/dependencies need to be fulfilled for the NSDocument to appear in the Window menu as normal?
I have checked MyDocument.h/.m (they are the standard stubs, virtually unchanged), and properties and outlets/delegates in MyDocument.xib, MainMenu.xib (none seem to be missing), and -Info.plist (which is identical to that of a New Project app). I'm experienced with XCode and Cocoa Touch, but not yet with Cocoa.
I'm willing to check things and write test code and give quick feedback, if you would help me over this last hurdle :)
I just had the same problem, and solved it by creating a reference to the window, and showing the window when the nib gets loaded:
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
[super windowControllerDidLoadNib:aController];
[window makeKeyAndOrderFront: self];
}
The cause of the problem is still unknown to me. If after trying that it doesn't work, try debugging it. You may discover the real cause, for example the window may have been already deallocated because there isn't any strong reference (not even in NSApp) to it.
Related
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 having a odd problem with an NSDocument-based application I am writing. When I first create a document and save it everything works as it should. However, when I reopen the document (which works just fine), neither "Save", "Save as" nor "Revert to saved" in the main menu seem to have any effect. The method
- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
never gets called. The main menu "Close" behavior is also strange: it closes the main document window, but none of the ancillary windows. Again, this irregular behavior is only observed when the document is opened; clicking on "Close" in the main menu works as expected when the document is newly created. Other menu items, both the "Open" item and my own custom items work fine.
This is an application that was developed in Snow Leopard and then Lion, and it didn't have any problems then. I've recently upgraded to Mountain Lion, but I am not sure if the problems began there or if I did something to the project to cause the behavior. The current SDK being used to compile the app is 10.7.
Any info would be much appreciated, and thanks in advance,
c.
Well, if your application allows, you can use Core Data. That would certainly remove the bug and let you build your app only with bindings.
Well, it seems that I fixed it, but I have no idea how. After debugging I realized that the WindowController was indeed getting instantiated, so it wasn't that. I ended up combining an old version of the project with some of the new code which initially displayed the same behavior, but at some point it didn't anymore. I wish I knew what I did to both break it and fix it, but I'm glad it works now!
And thanks Moray, I think it is time to move to Core Data.
Thanks all,
c.
I'm trying to get my NSWindow to:
Be visible on all Spaces
Be visible when showing the Desktop (by pressing F11)
Not be visible in Mission Control/Expose
The following does exactly that, but with a side effect:
[self setCollectionBehavior: NSWindowCollectionBehaviorCanJoinAllSpaces
| NSWindowCollectionBehaviorStationary ];
When switching to the Dashboard on Mac OS X Lion, the window remains visible alone with Dashboard items for a second, then it is hidden.
Is this expected behavior or a bug? Users of my app find it confusing to see the window on the Dashboard before they disappear. I would have expected them to only show on Spaces and not the Dashboard.
I looked at http://cocoadev.com/wiki/DontExposeMe searching for workaround
nothing really worked except.
self.window.level = kCGDesktopWindowLevel;
now maybe DETECT changes to expose and set that then :) ...
see How can one detect Mission Control or Command-Tab switcher superseding one's program in OS X? for that :)
maybe an answer will come up there
I was able to reproduce this behaviour and I think it's just a bit of faulty animation on Apple's side.
Just so I can explain this better, create a new project, add these two lines to applicationDidFinishLaunching:, and run it.
[self.window setCollectionBehavior: NSWindowCollectionBehaviorCanJoinAllSpaces | NSWindowCollectionBehaviorStationary ];
[self.window setHidesOnDeactivate: YES];
(self.window is the window that is created automatically when creating a new project. it doesn't really matter here anyway, just as long as it is a window that appears on the screen)
Now notice this behaviour: when changing from one space where you can see your window to another in which there are other windows from other apps (and so your window is supposed to disappear since your app will be deactivated), your window only disappears when the animation finishes. So, what is happening?
Here's what I think it happens: when switching from one space to another, windows that show on all spaces only react to the change after the animation, hence the brief appearence of your window on the dashboard. I think you'll notice it disappears exactly when the slide animation ends.
So, unfortunately, I don't know how to fix your problem. It just seems to happen this way.
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).
I am currently working on a web browser project from Apple's Mac Dev site.
I have completed the project, but have a bit of a problem. I have created the project as a Document-Based Cocoa Application, and now whenever I enter text in any text field on the web, the red traffic light button shows a black dot in the middle that signifies an unsaved document. When I try to close the window or entirely quit the application, a warning pops up like that in TextEdit or Pages where it alerts me to unsaved changes. It's not too much of a problem, but I would like if someone could please tell me how to remove that feature of a Cocoa Document-Based Application.
Why a document based application if your application isn't document based? Document based applications inherently include the concept of open and save; it is a fundamental part of what they are.
In any case, you could "work around" this by configuring NSDocument appropriately; override the proper methods and otherwise muck with the change count & dirty state of the document. But it'll be just that, a workaround. The documentation for NSDocument has all the information you need.
A cleaner overall solution would be to refactor your app to not use NSDocument. Creating multiple windows is quite straightforward in Cocoa (an action method tied to a menu item where the action method loads a nib file; if I remember correctly, you could even use NSWindowController still).
An easier solution would simply be to override the isDocumentEdited method to always return NO.
- (BOOL)isDocumentEdited {
return NO;
}