Mac OS X Cocoa single window application architecture - objective-c

I cannot understand how to design an application in optimal way for a single window application to work in Mac OS X. I would prefer a single document - single window application (I'm not coding a utility application), but it is not clear where should I initialize a window content.
On iOS I should use -[UIViewController viewDidLoad] or -[UIViewController viewWillAppear:] method of a root view controller for that purpose.
Could you please advice me any tutorial or explain how to deal with NSDocument - NSDocumentController - NSWindowController - NSViewController classes?
Thanks for your answers. :-)

You could put your window logic into your AppDelegate, but I discourage it. I recommend doing your own separate NSWindowController subclass to control the window, even for a single-window app. It's a very nice separation.
I don't see why one would want to use NSDocumentController for a single-window app. NSViewController is meant to control your custom views. It's usually not used in the average simple Mac app, unless you have some custom views you want to control specially.
So, in your AppDelegate's, say, applicationDidFinishLaunching:, you would allocate and initialize the window controller and show the window.
There is a good chapter in "Cocoa Programming for Mac OS X" by Hillegass on how to work with window controllers. Apple's docs also have some material on it, of course.

Related

NSTabView vs NSTabViewController -- When to use the controller?

The NSTabViewController was only introduced in OS X v10.10, so NSTabView already provides everything you need for creating a tab view. When would you use a NSTabViewController, and is it only there to be subclassed?
I would use NSTabViewController to get rid of a lot of code I used to have to write to have a tab view and transition between those views (most often done in Preference windows in Mac apps).
You'd obviously have to be 10.10 only, but these days that's a safe bet.
As for subclassing it, judging by the api I'd start without sub-classing it. You can set the style, the transition options (a nice benefit of using it!), and then call addTabViewItem: and let it do it's stuff.
If you compare iOS & OS X, you will feel OS X is bit deviated from MVC. OS X default 'new project' opens with AppDelegate as compared to iOS with 'ViewController'!
Now, it seems, Apple decided to make it by adding Controller as well. So that the view NSTabView is controlled by NSTabViewController.
And yes if you design to subclass it and use that should reduce your job. Same thing is mentioned even in Apple Documentation.

Xcode: How should I organize my multi-window user-interface project?

Note: Using Objective-C, Cocoa, and Xcode.
At first, I did all my programming in the AppDelegate and had all user-interface elements such as windows in the same '.xib' (nib file). This worked great at first, but then as my application became more advanced with more "features", everything became extremely cluttered and the file too long for my liking.
I'm now trying to progress. I'm wondering how I should (properly and efficiently) go about having a multi-window project? My plan was to have a .xib file for every window, and put only necessary things in the AppDelegate. I would then have a core file for all necessary calculations and such to be used in my application and a Main Controller file to control outlets and actions from all windows in my app. However, I'm quite new to Objective-C and have been running into SO many issues and problems trying to set up Window Controllers and stuff.
Am I even on the right path? Am I doing it wrong? How should I manage a multi-window user-interface application in Xcode?
Thanks in advance.
For multiple windows, I think it's best to use an NSWindowController for each, with it's associated xib file for the window. I'm not sure what you mean by "a Main Controller file to control outlets and actions from all windows" -- each window controller will have outlets to its own window. You can't connect outlets across multiple xib files. You can have one window in the MainMenu.xib file that you get by default when you create a project, and use that to launch other windows perhaps, but it's hard to offer any more specific advice without knowing how all your windows relate to each other.
After Edit:
If you want to open another window, have a menu item's action method be something like this:
self.controller = [[WindowController alloc] initWithWindowNibName:#"WindowController"];
[self.controller showWindow:nil];
Here, I have a property called controller to keep a strong reference to the new window controller. If you don't do that, the controller will be deallocated, so if you have multiple windows, that you want to show at the same time, you'll need properties to hold on to them.

How to use classes to control windows in Objective-C

I have been making applications for Mac with Objective-C for about a year now but due to not really understanding how to use classes properly I have only ever used the 'AppDelegate' files. I want to start using classes as soon as possible because from what I understand it's very bad practice to clump it in to one class. Basically, how do I have two windows, each controlled by it's own class. I understand how to make objects similar to NSString or something but don't understand how to have classes that control windows etc.
Thanks
Edit: Basically I want to know how to split up my application in to classes.
If I understand you correctly then you need to create individual controller classes sporting their own IBOutlets and IBActions and hook these up to your UI elements. To split up an existing application into smaller classes requires some knowledge of Object Oriented programming.
Alternatively, you might benefit from reading this (or a similar) book:
'Cocoa Programming for Mac OS X' by Aaron Hillegass.
Try looking for NSWindowController in the docs. You create a custom subclass of NSWindowController and a xib file for it. In the xib file, make sure you set the class on the File's Owner to your custom subclass, and make sure its window outlet is connected to the window in the xib. If all that sounds totally foreign, head for the books! =)
Then, in the code where you want to bring this window onto the screen, you create an instance of your custom subclass and associate it with the xib, like so:
MyCustomWindowController *controller = [[MyCustomWindowController alloc] initWithWindowNibName:#"myxib"]
[controller showWindow:self];
The xib loading system will hook up all your custom outlets and actions on the new controller, and you can show it or do other wonderful NSWindowController things.

Coming from iOS to OS X - where do I put my code?

I'm an iOS developer just starting to develop for OS X. In iOS, I always follow the MVC pattern, and put appropriate code in UIViewController subclasses. The App Delegate simply initializes the main view controller, and that's it. After that the view controllers handle all logic.
But in OS X, I seem to put everything in the app delegate. My app delegate class is now about 300 lines long and I am wondering how I can follow the same pattern I did in iOS. There are no view controllers!
What I mean is, what is the common accepted way to organize code for Mac Application?
You can create your own controller classes, and put an instantiation of these controller classes between the app delegate or model objects, and your view objects. Just because there is no pre-built view controller class, does not mean that you can't make your own similar partition, by creating custom controller classes of your own, as needed.

How to structure the code for a Cocoa Application

I'm writing a Cocoa application where I have an auto generated app delegate:(MyAppDelegate.h/MyAppDelegate.m)
So I am not sure of the best way to structure the class files for this Cocoa application. I understand MVC thoroughly (on the iPhone) but I'm having a block as to try organising the source properly in a Cocoa app.
I need to spawn two separate fullscreen OpenGL views. The problem is that I could simply create classes for "OpenGLView" then instantiate and call all this code into the app delegate, but it seems messy and it's aparently not the place to do it.
How would I best achieve the code structure?
Instantiate your application delegate in the MainMenu.xib file and hook it up. When I've done Cocoa fullscreen stuff, I've instantiated the views in the -applicationDidFinishLaunching method of the application delegate. It *is* messy, because for fullscreen views it doesn't really make sense to use interface builder. This is the same way that other folks do fullscreen apps in Cocoa.