Building an MVC based App for Mac OS X - NOT for iOS

  • I'm running
    OS X 10.8.3 (Mountain Lion)
    XCODE 4.6.1
    on MacBook

    When I create a NEW project
    Selecting
    Mac OS X => Application => Cocoa Application

    The end results does not automatically generate Controller.(m,h) files

    WHY NOT?

    You automatically get Controller files when creating an iOS based App.

    SO!  I've been trying to create Controller files that I can set up connections to like Target-Actions and Outlets in the Interface Editor.
    So far I have not been successful using instructions I found in the Apple Guide: Edit User Interfaces.

    Perhaps there is a better Guide on setting up an MVC for Mac OS X Apps or maybe there is a little know incantation some one might hare with me?

    Thanks

    YT

    I actually had a Snow Crash on my iMac. Maybe that is why I'm floundering.
  • On May 27, 2013, at 7:04 PM, YT wrote:

    > I'm running
    > OS X 10.8.3 (Mountain Lion)
    > XCODE 4.6.1
    > on MacBook
    >
    >
    > When I create a NEW project
    > Selecting
    > Mac OS X => Application => Cocoa Application
    >
    > The end results does not automatically generate Controller.(m,h) files

    It does, kind of. The app delegate may be considered a kind of controller, though not in the same sense as iOS.

    > WHY NOT?

    Because iOS is not Mac OS X--they may have some similar underpinnings, but they really are two different operating systems. Would you expect programing Windows to work the same OS X, considering that from a user-interaction point of view they share more concepts than iOS?

    The short answer is that unlike iOS, Mac apps do not necessarily have a primary window. In fact, a Mac app may have no GUI at all. Thus there is no good "default" choice for a controller.

    Really, in a Mac App what happens in main.m is all that is needed to launch a fully-functional app, even though it won't do anything. That's the Mac OS X starting point. Everything from there you have to build yourself.

    > You automatically get Controller files when creating an iOS based App.
    >
    > SO!  I've been trying to create Controller files that I can set up connections to like Target-Actions and Outlets in the Interface Editor.
    > So far I have not been successful using instructions I found in the Apple Guide: Edit User Interfaces.
    >
    > Perhaps there is a better Guide on setting up an MVC for Mac OS X Apps or maybe there is a little know incantation some one might hare with me?

    Mac OS X development os much more complicated than iOS development. It is not likely somehting you can just dive into without a learning curve. There are plenty of good books on Mac OS X development--you may want to pick one up.

    HTH,

    Keary Suska
    Esoteritech, Inc.
    "Demystifying technology for your home or business"
  • On May 27, 2013, at 6:46 PM, Keary Suska <cocoa-dev...> wrote:

    > Mac OS X development os much more complicated than iOS development. It is not likely somehting you can just dive into without a learning curve.

    Well, it’s different. Coming from OS X, I’ve found iOS UI development the more difficult of the two, because the UI is so much more limited, there is no document model or user-accessible filesystem, there’s very little you can do when in the background, etc.

    I don’t think either is diveable-into, even if you’re comfortable with the other.

    Anyway, to answer YT’s original question: To create new controllers you can use the New File… command and create a new OS X NSWindowController or NSViewController subclass. Xcode will put boilerplate code in the new files and even create .xibs. If you’re creating a document-based app you may want to create an NSDocument subclass, which is higher-level and abstracts the file I/O for you.

    —Jens
  • On May 27, 2013, at 7:56 PM, Jens Alfke <jens...> wrote:

    >
    > On May 27, 2013, at 6:46 PM, Keary Suska <cocoa-dev...> wrote:
    >
    >> Mac OS X development os much more complicated than iOS development. It is not likely somehting you can just dive into without a learning curve.
    >
    > Well, it’s different. Coming from OS X, I’ve found iOS UI development the more difficult of the two, because the UI is so much more limited, there is no document model or user-accessible filesystem, there’s very little you can do when in the background, etc.
    >
    > I don’t think either is diveable-into, even if you’re comfortable with the other.
    >
    > Anyway, to answer YT’s original question: To create new controllers you can use the New File… command and create a new OS X NSWindowController or NSViewController subclass. Xcode will put boilerplate code in the new files and even create .xibs. If you’re creating a document-based app you may want to create an NSDocument subclass, which is higher-level and abstracts the file I/O for you.
    >
    > —Jens

    SO...  I'm not sure if I did this correctly BUT...  I may have found a miss type in the Apple Guide: Edit User Interfaces

    Here is an extracted section

    Doc extract------------------------------
    Add a New Controller
    Every nib file is created with a File’s Owner object, which you link to the controller for the file. In the rare event that you need to add another controller to a nib file (to control a subview, for example), you need to create source files for the controller and add a controller object to the nib file so that you can make connections to the controller.
    To add a controller to a user interface file:
    Add the header and implementation files to your project.
    Select the Objective-C Class template, enter your custom controller class’s name, and specifyNSController as its superclass.
    From the Object library, drag an Object object to the Interface Builder dock.
    Select the custom view and specify its class as the class you added in step 1 by identifying it in the Identity inspector.

    To see the outlets and actions provided by the controller, select the controller object in the dock and open the Connections inspector. To add new actions or outlets to the controller, see “Make Connections Directly Between User Interface Objects and Your Source Files.
    DONE ----------------

    I followed the above selecting the custom view and it didn't work.

    I THINK in Step 3 "Select the custom view" should read "Select the Object object".

    SO what I am after is a ViewController.  I have a View placed in a Window where I use Quartz 2D to draw graphics into and need a Controller.  The Interface Builder was trying to force me to place ACTIONS AND OUTLETS in the Delegate files.
    I found that (as a nubee) very disconcerting and confidence shaking with regard to my experience with using an MVC.

    So in Step 1 above I created MyViewController files SuperClass NSView.
    In Step 2 & 3 I dragged a Object object into the Builder Doc and in the inspector classed it as MyViewController.
    THEN (perhaps an important tip) I went to the File's Owner in the Builder Doc, open the connection list and disconnected the auto generated Delegate connection from the File's Owner Outlets.
    THEN I opened the Helper Editor and it automatically brought up the Delegate.h
    THEN I manually switched the Helper file to MyController.h
    AND the BUILDER allowed me to set the ACTION and OUTLETs in the MyController file.

    Well my tests have worked so far SOoooo now I will give it go on placing graphics data into a model.
    AND the interactive element ACTIONS AND OUTLETS into the Controller.

    YT
  • On May 27, 2013, at 8:34 PM, YT <yt...> wrote:

    > SO what I am after is a ViewController.  I have a View placed in a Window where I use Quartz 2D to draw graphics into and need a Controller.  The Interface Builder was trying to force me to place ACTIONS AND OUTLETS in the Delegate files.
    > I found that (as a nubee) very disconcerting and confidence shaking with regard to my experience with using an MVC.

    It’s pretty common to have a window controller, and make it responsible for managing the views in the window too. (NSViewController wasn’t added until OS X 10.5 or so.)

    You can use NSViewController if you want to be more modular, especially if you want to use the same view (or view hierarchy) in multiple windows, but it’s not any more or less MVC compliant. It’s just a difference in what granularity you make your controllers. Also, “controller” is really just a role in a design pattern; it doesn’t have to inherit from some system class with “Controller” in the name to be a valid controller.

    —Jens
  • On May 27, 2013, at 20:34 , YT <yt...> wrote:

    > Here is an extracted section

    I found the section of documentation you're referring to (it wasn't easy, you didn't give us much to go on).

    The short answer to your concern is that this piece of documentation is just plain wrong. If you need to add a view-specific controller, it should be a NSViewController, or a subclass, and not a subclass of NSController. NSController subclasses serve a different purpose -- they are "mediating" controllers, which is a respectable name for class-wrapped glue code.

    If you're coming from iOS, the nearest equivalent to UIViewController is NSWindowController -- *not* NSViewController, and certainly not NSController.

    When starting a new Mac app, the Cocoa classes you need to pay immediate attention to are:

    -- the app delegate (a custom class you define)

    -- if it's a document-based app, a NSDocument subclass

    -- for each window in your app a NSWindowController subclass

    In the broadest MVC terms, the "C" is often a NSWindowController subclass. The "M" is often the app delegate *or* a NSDocument subclass, or is a more specialized object graph to which the app delegate or document holds a reference. The "V" is the window and its contained views.

    However, it's a bit difficult to advise you more specifically on this without knowing whether your app is document-based or non-document-based.

    Stay away from NSViewController until and unless you find that you need it, and know why you need it. It isn't UIViewController. Rather, it's a sort of specialized NSWindowController, but for independently-loaded views instead of windows.
  • On May 28, 2013, at 7:15 AM, Quincey Morris <quinceymorris...> wrote:
    > In the broadest MVC terms, the "C" is often a NSWindowController subclass. The "M" is often the app delegate *or* a NSDocument subclass, or is a more specialized object graph to which the app delegate or document holds a reference. The "V" is the window and its contained views.

    While it is true that many people use the app delegate as the model (aka a hidden singleton that is a dump for all sorts of stuff), I wouldn't recommend that.

    The app delegate is intended to provide behaviours for the application as shown in the Dock and Finder, and a root for global properties and actions exposed to AppleScript and other automation/scripting/interapplication communication mechanisms. If you have anything else, you should create a separate (often reusable) class that the application or application delegate creates.

    For document-based apps, NSApplication already does that by default, but you can modify the behaviour. For shoebox apps and the likes, you create an NSWindowController that implements the main window, and maybe another one for a preferences window. But only create them, keep their specific code out of the application and app delegate as much as possible. Otherwise your app delegate grows into a huge god-object and needs to be recompiled every time one of the other classes is changed even slightly, and worse, may cause all other files in your project to recompile every time you change it to adjust a method another object uses from it.

    In particular, only few menu items should be implemented by the application itself. Instead, most of them should be hooked up to the First Responder, where each window controller can then claim it using the responder chain when it is frontmost.

    Cheers,
    -- Uli Kusterer
    "The Witnesses of TeachText are everywhere..."
    http://www.zathras.de
  • In the latest set of responses to my query "Building an MVC based App for Mac OS X - NOT iOS"

    The question of - am I building a "Document Based App"?

    After reading the Apple Document "Designing a Document-Based Application" I can say NO, I don't believe I am building a Document Based App.

    I did run a test and created a NEW Project and checked the box "Create a Document-based App"
    AND no Controller files (.h,.m) were automatically generated.

    Which leads to the general mechanical problem of how does one create Controller files (.h,.m)?
    You get them auto created when working in iOS
    BUT they are not auto created when working in Mac OS X.

    Then the latest set of responses discuss which Controller to use once the "general mechanical how to create a controller" is answered.

    Jens Writes ------
    Anyway, to answer YT’s original question: To create new controllers you can use the New File… command and create a new OS X NSWindowController or NSViewController subclass. Xcode will put boilerplate code in the new files and even create .xibs. If you’re creating a document-based app you may want to create an NSDocument subclass, which is higher-level and abstracts the file I/O for you.
    ---------
    AND I found that to actually use any controller one creates via NEW File... as a Controller
    You have to disconnect the Auto generated Delegate from the Outlets Connection in the File's Owner Object in the IB Doc
    Please correct me if I am wrong about this point.

    All of you discuss the utilities of the following Controllers.
    NSWindowController
    NSViewController
    UIViewController
    NSController

    From a nubee Apple App programming point of view they all appear to be similar WHICH MEANS I will have to read more about each to be able to make an intelligent choice that fits my intended purpose.

    more later...

    YT
  • On May 28, 2013, at 10:01 , YT <yt...> wrote:

    > I did run a test and created a NEW Project and checked the box "Create a Document-based App"
    > AND no Controller files (.h,.m) were automatically generated.

    Actually, two controllers *were* generated:

    1. The app delegate. This object has the role of a controller, even though it starts out with nothing to do. Its controller behavior comes from code you add to it, as necessary.

    2. The NSDocument subclass. These objects are also controllers.

    > Which leads to the general mechanical problem of how does one create Controller files (.h,.m)?

    A MVC controller is just an object that behaves like a controller. It doesn't have to have "controller" in its name to behave like a controller. It can be of any class, and the class you choose depends on what it's supposed to do.

    Keep in mind that the MVC pattern is a very general pattern. A MVC "controller" is not the same as a "view controller". Putting this another way, a view controller is a kind of MVC controller, but not the only kind.

    Similarly, a MVC "view" is not necessarily a view. Rather, it's a component of your app design that interacts with the user. It may be implemented as a window, or as a view, or as a window with a hierarchy of views, or something more complex.

    Translating a MVC design pattern into an implementation is messier on the Mac than on iOS. That's because the objects used on the Mac grew up over time. iOS's UIViews and UIViewControllers were based on Mac concepts, but tried to unify the loose Mac architecture into something more consistent and rational.
  • On 28.05.2013, at 19:01, YT <yt...> wrote:
    > I did run a test and created a NEW Project and checked the box "Create a Document-based App"
    > AND no Controller files (.h,.m) were automatically generated.

    "Controller" is a pattern, not a class name. When you create a document-based app, it creates a document class for you. This owns an NSWindowController (by default). Usually you put all your controller-ish stuff in the document (which is a kind of controller), though you can also subclass NSWindowController and have it create one of those, which is done especially if a document can consist of several windows.

    Cheers,
    -- Uli Kusterer
    "The Witnesses of TeachText are everywhere..."
    http://www.masters-of-the-void.com
  • On 28.05.2013, at 19:01, YT <yt...> wrote:
    > You have to disconnect the Auto generated Delegate from the Outlets Connection in the File's Owner Object in the IB Doc
    > Please correct me if I am wrong about this point.
    >
    > All of you discuss the utilities of the following Controllers.
    > NSWindowController
    > NSViewController
    > UIViewController
    > NSController
    >
    > From a nubee Apple App programming point of view they all appear to be similar WHICH MEANS I will have to read more about each to be able to make an intelligent choice that fits my intended purpose.

    My recommendation for reading about Mac programming is this book:

    <http://www.amazon.com/Cocoa-Programming-Mac-4th-Edition/dp/0321774086>

    It is very good, and walks you through creating a Mac application, explaining things along the way.

    Cheers,
    -- Uli Kusterer
    "The Witnesses of TeachText are everywhere..."
  • On 28.05.2013, at 19:28, Quincey Morris <quinceymorris...> wrote:
    > Similarly, a MVC "view" is not necessarily a view. Rather, it's a component of your app design that interacts with the user. It may be implemented as a window, or as a view, or as a window with a hierarchy of views, or something more complex.

    Examples of Cocoa/Mac classes that are views in the MVC sense, but not in the NSView/UIView sense:

    NSWindow
    NSMenu
    NSMenuItem
    NSCell
    Pretty much any NSResponder, though Smalltalk purists might disagree.

    Cheers,
    -- Uli Kusterer
    http://stacksmith.org
previous month may 2013 next month
MTWTFSS
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
Go to today