CD: Creating a managed object

  • I have a simple app with a view with a mouse down handler. The simple
    core data model has an entity to track where the user has clicked.
    The basic architecture I have come up with is to add an outlet to the
    view for the NSArrayController controlling the point entities. This
    outlet is connected in IB to the controller. When the view is clicked
    mouseDown: is called:

    IBOutlet NSArrayController *nsa;

    .....

    -(void) mouseDown: (NSEvent *)event {
        [nsa insert: self];
    }

    Is the view holding a reference to the controller a reasonable
    architecture? I'm kind of doing what a plus button would do to send
    add: to the controller to create a new object.

    If this is OK, the next step is to change the insert to an addObject.
    Getting code out of the Core Data Programming Guide I'd do something
    like:

    -(void) mouseDown: (NSEvent *)event {
        NSManagedObject *point = [NSEntityDescription
    insertNewObjectForEntityForName: @"Point" inManagedObjectContext:
    context]; // Where do I get 'context'?
        [point setX: event.x]; // pseudo code
        [point setY: event.y];
        [nsa addObject: point];
    }

    Problem I have with the above is that we are in a view and the
    managed object context belongs to the document, which the view does
    not know about the context, which makes me think there is something
    wrong with this architecture.

    So is there a better way of creating a managed object when a click is
    received in a view? Or if this is a legitimate way of doing it, how
    do I get the right context to insert the managed object into?

    Thanks
    Ian Joyner
    Sportstec
  • On May 27, 2007, at 11:01 PM, Ian Joyner wrote:
    > Or if this is a legitimate way of doing it, how do I get the right
    > context to insert the managed object into?
    >
    Where does it come from here:

    > [nsa insert: self];
    >
    ...?

    (Hint: <http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Cla
    sses/NSObjectController_Class/Reference/Reference.html
    >)

    mmalc
  • On 28/05/2007, at 5:50 PM, mmalc Crawford wrote:

    >
    > On May 27, 2007, at 11:01 PM, Ian Joyner wrote:
    >> Or if this is a legitimate way of doing it, how do I get the right
    >> context to insert the managed object into?
    >>
    > Where does it come from here:
    >
    >> [nsa insert: self];
    >>
    > ...?
    >
    > (Hint: <http://developer.apple.com/documentation/Cocoa/Reference/
    > ApplicationKit/Classes/NSObjectController_Class/Reference/
    > Reference.html>)

    Thanks, was getting late in the afternoon, and I went straight to
    NSController, missing NSObjectController.

    I'm still curious as to whether this is the best way to do this
    (creating an NSManagedObject in a view) or if there is a more subtle
    way to set it up with bindings? I'm sure this must be a common thing
    to do, but haven't seen it in any sample code.

    Ian
  • On May 28, 2007, at 3:03 AM, Ian Joyner wrote:

    > I'm still curious as to whether this is the best way to do this
    > (creating an NSManagedObject in a view) or if there is a more subtle
    > way to set it up with bindings? I'm sure this must be a common thing
    > to do, but haven't seen it in any sample code.
    >
    It's not clear why bindings are relevant to object creation?
    What would your architecture be if you weren't using Core Data?
    Why can you not just use the array controller to create a new object?

    mmalc
  • On 29/05/2007, at 8:57 AM, mmalc Crawford wrote:

    >
    > On May 28, 2007, at 3:03 AM, Ian Joyner wrote:
    >
    >> I'm still curious as to whether this is the best way to do this
    >> (creating an NSManagedObject in a view) or if there is a more
    >> subtle way to set it up with bindings? I'm sure this must be a
    >> common thing to do, but haven't seen it in any sample code.
    >>
    > It's not clear why bindings are relevant to object creation?
    > What would your architecture be if you weren't using Core Data?
    > Why can you not just use the array controller to create a new object?

    OK, even if this is not quite right, it's only a small routine to
    refactor, so I think this is pretty clean (the only thing I'm uneasy
    about is manipulating a model object in a view, but perhaps that is
    alright.

    IBOutlet NSArrayController *nsa;

    ...

    -(void) mouseDown: (NSEvent *)event {
        NSPoint p = [event locationInWindow];
        NSManagedObject *mo = [nsa newObject];
        [mo setValue: [NSNumber numberWithFloat: p.x] forKey: @"x"];
        [mo setValue: [NSNumber numberWithFloat: p.y] forKey: @"y"];
    }

    Even though I had to write some code (whereas a lot in Cocoa happens
    without any code), this seems pretty minimalist for something I can't
    think of doing another way.

    Thanks
    Ian
  • A suggestion then would be to write this mouseDown: call so that it
    sends a message to the view's delegate.  This would then pass control
    back over to the controller when the mouse down is detected and
    preserve the MVC.

    Marcus S. Zarra
    Zarra Studios LLC
    Simply Elegant Software for OS X
    www.zarrastudios.com

    On May 28, 2007, at 9:42 PM, Ian Joyner wrote:

    > OK, even if this is not quite right, it's only a small routine to
    > refactor, so I think this is pretty clean (the only thing I'm
    > uneasy about is manipulating a model object in a view, but perhaps
    > that is alright.
    >
    > IBOutlet NSArrayController *nsa;
    >
    > ...
    >
    > -(void) mouseDown: (NSEvent *)event {
    > NSPoint p = [event locationInWindow];
    > NSManagedObject *mo = [nsa newObject];
    > [mo setValue: [NSNumber numberWithFloat: p.x] forKey: @"x"];
    > [mo setValue: [NSNumber numberWithFloat: p.y] forKey: @"y"];
    > }
    >
  • On May 28, 2007, at 11:42 PM, Ian Joyner wrote:
    > OK, even if this is not quite right, it's only a small routine to
    > refactor, so I think this is pretty clean (the only thing I'm
    > uneasy about is manipulating a model object in a view, but perhaps
    > that is alright.

      I think you need to go back to the fundamentals in the
    documentation and put in some serious review/research time before
    continuing any further. There's simply no good reason for your approach.

      You should consider data source and delegate style methods (like
    NSTableView). Study NSTableView's design and do it that way.
    Something like -myView:didClickAtPoint: ... if that's sent to a
    delegate (your controller) the delegate can respond by creating a new
    model object and any housekeeping.

      Any time you have a view directly interacting with a model or vice-
    versa, your design is incorrect.

    --
    I.S.
  • On 29/05/2007, at 9:18 PM, I. Savant wrote:

    > On May 28, 2007, at 11:42 PM, Ian Joyner wrote:
    >> OK, even if this is not quite right, it's only a small routine to
    >> refactor, so I think this is pretty clean (the only thing I'm
    >> uneasy about is manipulating a model object in a view, but perhaps
    >> that is alright.
    >
    >
    > I think you need to go back to the fundamentals in the
    > documentation and put in some serious review/research time before
    > continuing any further.

    Um, that's exactly what I am doing! Unfortunately, all of Apple's
    tutorials and Core Data documentation and examples (that I've seen)
    deal with simple cases where you connect an 'add' button to an
    NSArrayController through IB's binding interface. Works nicely
    without any code, but how to handle CD entities being created in
    other means in response to other user actions is the question. (That
    bit already works manually, but I want to automate it and remove the
    add button (and record coordinates).)

    > There's simply no good reason for your approach.

    It works, that's a good reason so most people would go no further
    (OK, I've been around for long enough to see a little further down
    the track). Some people would argue that MVC is a heavy-weight
    pattern and it's cracking a peanut with a sledgehammer.
    >
    > You should consider data source and delegate style methods (like
    > NSTableView). Study NSTableView's design and do it that way.
    > Something like -myView:didClickAtPoint: ... if that's sent to a
    > delegate (your controller) the delegate can respond by creating a
    > new model object and any housekeeping.

    But a delegate is still part of the V in MVC – it's really just an
    extension of the view class without subclassing. It makes sense for
    NSTableView to do this, since it needs to be left open for others to
    use it. In my case, I have a simple custom view, which is only a part
    of this application, so will not need extension or clever features in
    the future. There's not much distinction between mouseDown and
    didClickAtPoint – you still need to intercept it somewhere.

    What occurs to me is to subclass NSArrayController, and change the
    add method to handle the model object:

    MyArrayController.....

    -(void) add: (NSEvent *)event { // OK, I don't think covariance is
    allowed (or even needed) in Obj-C
        NSPoint p = [event locationInWindow];
        NSManagedObject *mo = [nsa newObject];
        [mo setValue: [NSNumber numberWithFloat: p.x] forKey: @"x"];
        [mo setValue: [NSNumber numberWithFloat: p.y] forKey: @"y"];
    }

    In the view:

    IBOutlet MyArrayController *nsa;  // Connected in IB

    ...

    -(void) mouseDown: (NSEvent *)event {
        [nsa add: event];
    }

    I think this follows the MVC pattern Figure 6.3 on p123 of Hillegas,
    just the NSButtons have been replaced by my view. Of course if there
    is another way to make this work without subclassing
    NSArrayController, then I'm happy to hear. If this is the Cocoa
    intended way of handling this situation, I'm happy to hear that too.

    > Any time you have a view directly interacting with a model or
    > vice-versa, your design is incorrect.

    That's exactly my original point. However, it has to be said that
    there are lots of working programs with incorrect designs. I prefer
    the former, but being a purist (so I think we're on the same side), I
    want a clean design as well. Someone even said, if you are writing
    code in Cocoa you are probably doing it wrong. I tend to get the
    feeling that's good advice.

    Sorry, I know you were probably trying to be helpful, but there is a
    little bit too much of "go away and read the documents" (pointers are
    fine) whenever someone asks a question in these Cocoa groups, and you
    might find someone already has read all the documents and scanned the
    example code. It's not the same as a university tutor telling a
    student to find it out for themselves (I've been there and done that
    too). I think the use of Core Data and Bindings is still so new (many
    people are still doing things the old way), that a lot of required
    patterns are not widely known yet. I'm just exploring well what
    really is the best way of doing things. I think people are more
    tolerant of idiot questions in the WebObjects groups (reason for
    question might not be so idiotic after all).

    Ian
  • The view's delegate is not part of the view in MVC.  Your delegate to
    the view is normally a (window) controller not another view object.

    As for subclassing NSArrayController, that is unnecessary.  If you
    configure the NSArrayController to contain instances of your
    NSManagedObject (as opposed to NSDictionary objects) then you can
    call insert: on it and it will create a new object for you.  However,
    if you are doing that in the view then that is breaking the model also.

    As a few people have suggested, you could have the view call a method
    on its delegate (a controller) passing in the information and let the
    delegate handle object creation.  This fits the MVC pattern.

    Marcus S. Zarra
    Zarra Studios LLC
    www.zarrastudios.com
    Simply Elegant Software for OS X

    On May 29, 2007, at 6:17 PM, Ian Joyner wrote:

    > On 29/05/2007, at 9:18 PM, I. Savant wrote:
    >
    >> On May 28, 2007, at 11:42 PM, Ian Joyner wrote:
    >>> OK, even if this is not quite right, it's only a small routine to
    >>> refactor, so I think this is pretty clean (the only thing I'm
    >>> uneasy about is manipulating a model object in a view, but
    >>> perhaps that is alright.
    >>
    >>
    >> I think you need to go back to the fundamentals in the
    >> documentation and put in some serious review/research time before
    >> continuing any further.
    >
    > Um, that's exactly what I am doing! Unfortunately, all of Apple's
    > tutorials and Core Data documentation and examples (that I've seen)
    > deal with simple cases where you connect an 'add' button to an
    > NSArrayController through IB's binding interface. Works nicely
    > without any code, but how to handle CD entities being created in
    > other means in response to other user actions is the question.
    > (That bit already works manually, but I want to automate it and
    > remove the add button (and record coordinates).)
    >
    >> There's simply no good reason for your approach.
    >
    > It works, that's a good reason so most people would go no further
    > (OK, I've been around for long enough to see a little further down
    > the track). Some people would argue that MVC is a heavy-weight
    > pattern and it's cracking a peanut with a sledgehammer.
    >>
    >> You should consider data source and delegate style methods (like
    >> NSTableView). Study NSTableView's design and do it that way.
    >> Something like -myView:didClickAtPoint: ... if that's sent to a
    >> delegate (your controller) the delegate can respond by creating a
    >> new model object and any housekeeping.
    >
    > But a delegate is still part of the V in MVC – it's really just an
    > extension of the view class without subclassing. It makes sense for
    > NSTableView to do this, since it needs to be left open for others
    > to use it. In my case, I have a simple custom view, which is only a
    > part of this application, so will not need extension or clever
    > features in the future. There's not much distinction between
    > mouseDown and didClickAtPoint – you still need to intercept it
    > somewhere.
    >
    > What occurs to me is to subclass NSArrayController, and change the
    > add method to handle the model object:
    >
    > MyArrayController.....
    >
    > -(void) add: (NSEvent *)event { // OK, I don't think covariance is
    > allowed (or even needed) in Obj-C
    > NSPoint p = [event locationInWindow];
    > NSManagedObject *mo = [nsa newObject];
    > [mo setValue: [NSNumber numberWithFloat: p.x] forKey: @"x"];
    > [mo setValue: [NSNumber numberWithFloat: p.y] forKey: @"y"];
    > }
    >
    > In the view:
    >
    > IBOutlet MyArrayController *nsa;  // Connected in IB
    >
    > ...
    >
    > -(void) mouseDown: (NSEvent *)event {
    > [nsa add: event];
    > }
    >
    > I think this follows the MVC pattern Figure 6.3 on p123 of
    > Hillegas, just the NSButtons have been replaced by my view. Of
    > course if there is another way to make this work without
    > subclassing NSArrayController, then I'm happy to hear. If this is
    > the Cocoa intended way of handling this situation, I'm happy to
    > hear that too.
    >
    >> Any time you have a view directly interacting with a model or
    >> vice-versa, your design is incorrect.
    >
    > That's exactly my original point. However, it has to be said that
    > there are lots of working programs with incorrect designs. I prefer
    > the former, but being a purist (so I think we're on the same side),
    > I want a clean design as well. Someone even said, if you are
    > writing code in Cocoa you are probably doing it wrong. I tend to
    > get the feeling that's good advice.
    >
    > Sorry, I know you were probably trying to be helpful, but there is
    > a little bit too much of "go away and read the documents" (pointers
    > are fine) whenever someone asks a question in these Cocoa groups,
    > and you might find someone already has read all the documents and
    > scanned the example code. It's not the same as a university tutor
    > telling a student to find it out for themselves (I've been there
    > and done that too). I think the use of Core Data and Bindings is
    > still so new (many people are still doing things the old way), that
    > a lot of required patterns are not widely known yet. I'm just
    > exploring well what really is the best way of doing things. I think
    > people are more tolerant of idiot questions in the WebObjects
    > groups (reason for question might not be so idiotic after all).
    >
    > Ian
  • On 30/05/2007, at 10:26 AM, Marcus S. Zarra wrote:

    > The view's delegate is not part of the view in MVC.  Your delegate
    > to the view is normally a (window) controller not another view object.

    By "view object", do you mean object derived from NSView? To be a
    part of the V, an object does not have to be an explicit view object,
    just a general supporter object working within the V of MVC. And
    NSWindowController is a controller not in the NSController hierarchy
    (but I think this is historical more than anything).

    >
    > As for subclassing NSArrayController, that is unnecessary.

    Right, by my reasoning above, I don't have to inherit NSController
    for a class to be in the Controller group, so I could have my own
    controller with the NSArrayController as a reference to do as I had
    in the view class. I had not thought that subclassing anything in the
    NSController hierarchy was a recommended suggestion (in any of
    Apple's docs that I've seen). However, that intermediate controller
    object only removes a little bit of code from the view class and
    since the view class references and uses it, it's heavily related to
    the V anyway. But the purpose of the C layer is to remove all that
    messy code from the V and M layers. So it's probably a better
    approach in the long run as the app gets bigger and more messy (I
    hope not).

    > If you configure the NSArrayController to contain instances of
    > your NSManagedObject (as opposed to NSDictionary objects) then you
    > can call insert: on it and it will create a new object for you.
    > However, if you are doing that in the view then that is breaking
    > the model also.
    >
    > As a few people have suggested, you could have the view call a
    > method on its delegate (a controller) passing in the information
    > and let the delegate handle object creation.  This fits the MVC
    > pattern.

    I got your suggestion from your last post – still looking into it.
    NSView doesn't have a delegate, and it seems a bit artificial to
    build the delegate mechanism into an app class (a reusable framework
    class would be entirely different). Then again the "Learning Cocoa"
    book says MVC is not a hard and fast thing (is there going to be a
    new version of this book after that which is under NDA is released?).
    I suspect we are (maybe particularly me) are trying to make MVC too
    hard and fast.

    Anyway, I have just found another example to look at, so will let you
    know how I go. Thanks for your suggestions.
    >
    > Marcus S. Zarra
    > Zarra Studios LLC
    > www.zarrastudios.com
    > Simply Elegant Software for OS X
    >
    > On May 29, 2007, at 6:17 PM, Ian Joyner wrote:
    >
    >> On 29/05/2007, at 9:18 PM, I. Savant wrote:
    >>
    >>> On May 28, 2007, at 11:42 PM, Ian Joyner wrote:
    >>>> OK, even if this is not quite right, it's only a small routine
    >>>> to refactor, so I think this is pretty clean (the only thing I'm
    >>>> uneasy about is manipulating a model object in a view, but
    >>>> perhaps that is alright.
    >>>
    >>>
    >>> I think you need to go back to the fundamentals in the
    >>> documentation and put in some serious review/research time before
    >>> continuing any further.
    >>
    >> Um, that's exactly what I am doing! Unfortunately, all of Apple's
    >> tutorials and Core Data documentation and examples (that I've
    >> seen) deal with simple cases where you connect an 'add' button to
    >> an NSArrayController through IB's binding interface. Works nicely
    >> without any code, but how to handle CD entities being created in
    >> other means in response to other user actions is the question.
    >> (That bit already works manually, but I want to automate it and
    >> remove the add button (and record coordinates).)
    >>
    >>> There's simply no good reason for your approach.
    >>
    >> It works, that's a good reason so most people would go no further
    >> (OK, I've been around for long enough to see a little further down
    >> the track). Some people would argue that MVC is a heavy-weight
    >> pattern and it's cracking a peanut with a sledgehammer.
    >>>
    >>> You should consider data source and delegate style methods
    >>> (like NSTableView). Study NSTableView's design and do it that
    >>> way. Something like -myView:didClickAtPoint: ... if that's sent
    >>> to a delegate (your controller) the delegate can respond by
    >>> creating a new model object and any housekeeping.
    >>
    >> But a delegate is still part of the V in MVC – it's really just an
    >> extension of the view class without subclassing. It makes sense
    >> for NSTableView to do this, since it needs to be left open for
    >> others to use it. In my case, I have a simple custom view, which
    >> is only a part of this application, so will not need extension or
    >> clever features in the future. There's not much distinction
    >> between mouseDown and didClickAtPoint – you still need to
    >> intercept it somewhere.
    >>
    >> What occurs to me is to subclass NSArrayController, and change the
    >> add method to handle the model object:
    >>
    >> MyArrayController.....
    >>
    >> -(void) add: (NSEvent *)event { // OK, I don't think covariance is
    >> allowed (or even needed) in Obj-C
    >> NSPoint p = [event locationInWindow];
    >> NSManagedObject *mo = [nsa newObject];
    >> [mo setValue: [NSNumber numberWithFloat: p.x] forKey: @"x"];
    >> [mo setValue: [NSNumber numberWithFloat: p.y] forKey: @"y"];
    >> }
    >>
    >> In the view:
    >>
    >> IBOutlet MyArrayController *nsa;  // Connected in IB
    >>
    >> ...
    >>
    >> -(void) mouseDown: (NSEvent *)event {
    >> [nsa add: event];
    >> }
    >>
    >> I think this follows the MVC pattern Figure 6.3 on p123 of
    >> Hillegas, just the NSButtons have been replaced by my view. Of
    >> course if there is another way to make this work without
    >> subclassing NSArrayController, then I'm happy to hear. If this is
    >> the Cocoa intended way of handling this situation, I'm happy to
    >> hear that too.
    >>
    >>> Any time you have a view directly interacting with a model or
    >>> vice-versa, your design is incorrect.
    >>
    >> That's exactly my original point. However, it has to be said that
    >> there are lots of working programs with incorrect designs. I
    >> prefer the former, but being a purist (so I think we're on the
    >> same side), I want a clean design as well. Someone even said, if
    >> you are writing code in Cocoa you are probably doing it wrong. I
    >> tend to get the feeling that's good advice.
    >>
    >> Sorry, I know you were probably trying to be helpful, but there is
    >> a little bit too much of "go away and read the
    >> documents" (pointers are fine) whenever someone asks a question in
    >> these Cocoa groups, and you might find someone already has read
    >> all the documents and scanned the example code. It's not the same
    >> as a university tutor telling a student to find it out for
    >> themselves (I've been there and done that too). I think the use of
    >> Core Data and Bindings is still so new (many people are still
    >> doing things the old way), that a lot of required patterns are not
    >> widely known yet. I'm just exploring well what really is the best
    >> way of doing things. I think people are more tolerant of idiot
    >> questions in the WebObjects groups (reason for question might not
    >> be so idiotic after all).
    >>
    >> Ian
  • On May 30, 2007, at 1:50 AM, Ian Joyner wrote:
    > I got your suggestion from your last post – still looking into it.
    > NSView doesn't have a delegate, and it seems a bit artificial to
    > build the delegate mechanism into an app class (a reusable
    > framework class would be entirely different).

      NSView is *meant* to be subclassed. It's all but useless to
    developers otherwise. You can add anything to it you want / need to
    get things done. It's not artificial, it's what you're meant to do.
    Whether it's packaged into a framework or not is entirely irrelevant,
    if you want a custom view, you subclass NSView. Additionally, "a
    delegate" can be whatever you want it to be. So can the delegate
    methods you add. It's a messaging mechanism that allows others to
    help decide how the delegator is to do things. That's all.

      Regarding MVC design, it's fairly flexible and there's no one
    right way to design your app according to this pattern, but outright
    breaking it in a Cocoa app is quite simply a bad idea. Not because
    all applications that don't adopt the design pattern are inherently
    flawed, but because *Cocoa* applications use an API designed this way.

      You may have been offended by my telling you to go back and read
    some more, but you're going to have to get over it. The plain fact
    is, you're trying to run before you walk and you're missing some big,
    important points along the way and it shows. You're being
    argumentative with everyone who's given you answers, which suggests
    you're only interested in making people tell you how to make it work
    *your* way. Good luck with that.

    --
    I.S.
  • On 30/05/2007, at 9:09 PM, I. Savant wrote:

    > On May 30, 2007, at 1:50 AM, Ian Joyner wrote:
    >> I got your suggestion from your last post – still looking into it.
    >> NSView doesn't have a delegate, and it seems a bit artificial to
    >> build the delegate mechanism into an app class (a reusable
    >> framework class would be entirely different).
    >
    > NSView is *meant* to be subclassed. It's all but useless to
    > developers otherwise. You can add anything to it you want / need to
    > get things done. It's not artificial, it's what you're meant to do.
    > Whether it's packaged into a framework or not is entirely
    > irrelevant, if you want a custom view, you subclass NSView.
    > Additionally, "a delegate" can be whatever you want it to be. So
    > can the delegate methods you add. It's a messaging mechanism that
    > allows others to help decide how the delegator is to do things.
    > That's all.

    OK, my last post simplified the fact that I am subclassing NSView
    (and as was shown in my original posts). I'm not going to use
    delegation just because I can, but only if it's appropriate (better
    to be tasteful in design like Apple, not Microsoft).
    >
    > Regarding MVC design, it's fairly flexible and there's no one
    > right way to design your app according to this pattern, but
    > outright breaking it in a Cocoa app is quite simply a bad idea. Not
    > because all applications that don't adopt the design pattern are
    > inherently flawed, but because *Cocoa* applications use an API
    > designed this way.

    I was not arguing against MVC, rather for it. (I know there are some
    irritating people who just go round poking holes in things, but that
    was not the purpose of my question.) The simple question was what is
    the best way to handle this using Cocoa Bindings and Core Data, given
    that the simple situation I have outlined has no sample code, is not
    explained in Apple docs or tuts, and Bindings are generally too new
    to be in most books. Core data is certainly not covered in any Cocoa
    books yet. Here is a survey:

                                                  Bindings
    Core data
    Anguish et al (2003)            no                          no
    Learning Cocoa (2001)      no                          no    (I
    suspect not in Learning Cocoa with Objective-C either)
    Hillegas (2004)                    yes                        no
    Hillegas and Dalrymple      no                          no
    Zobkiw (2003)                        no                        no
    Kochan (2003)                      no                        no
    (wouldn't expect it in a new version either)
    Singh (2006)                          no
    no    (wouldn't expect it in here)

    As you can see not a lot in there. Core Data Programming Guide shows
    how to create entities, but not where to put the code. All the sample
    code (both Apple's and others I've seen) show how to add tables and
    'add' buttons. It's all very IT, but I think CD is more than that.

    MVC is about putting objects into clusters and reducing surface area
    between those clusters to avoid complexity and thus programming error
    and making things easy to extend in the future (rather like an
    argument I had about gotos with someone recently). That's exactly
    what my question was about – finding an architecture for something
    that hasn't been covered elsewhere.

    > You may have been offended by my telling you to go back and read
    > some more, but you're going to have to get over it.

    Well, see the above. Your diagnosis is wrong.

    > The plain fact is, you're trying to run before you walk and you're
    > missing some big, important points along the way and it shows.

    I've been doing Mac programming since 1984, MacApp since version 0.3
    (until they wrecked it by converting it to C++), OS X since 2000, and
    WebObjects for several years. And in another life loads of system-
    level programming in ALGOL. I've done enough to know there's always
    more to know. Your diagnosis is wrong again.

    > You're being argumentative with everyone who's given you answers,

    No, I've taken issue with the sentiment of "go away you don't know
    enough to play with us big boys yet". If you do this to someone who
    has a lot of Mac and other experience, how will genuine newbies
    feel.... they'll just go and do windows where it's easier (to get a
    job and pays better). So don't be patronizing in your responses to
    people, it's not good netiquette, whatever level they are at.

    > which suggests you're only interested in making people tell you how
    > to make it work *your* way.

    I didn't have a way, some ideas, so I posted here to find out how
    other people would handle the situation, not to be lectured on going
    and doing more reading – I've read it all. I'm interested in what the
    alternatives are and the tradeoffs and the decisions to make in
    adopting an approach. Your diagnosis is wrong again.

    > Good luck with that.

    I think this could have been an interesting and constructive
    discussion. There is always a case for questions like here's how I'm
    thinking do others have better suggestions.
  • Reviewing this original question and after some thoughts from Mr
    Crawford, I think it is more about bindings and the NSController
    architecture (no surprise there), rather than Core Data.

    With Cocoa bindings, you just connect up the bindings in IB and
    messages just get passed to the right things and it works. The great
    thing about Cocoa bindings is you don't have to write all that messy
    code that you normally have to in the controller part (thanks to KVC/
    O). However, what I needed to do was to record something that
    happened in the view in the CD model entities (this isn't your
    typical IT app). (It's actually a bit like a game, but user actions
    are recorded, hence use of CD.)

    I didn't like putting manipulation of a CD entity in the view, but
    using bindings, the controller bit seemed rather closed off. So the
    question is how to get controller code into the bindings scheme of
    things.

    It occurred to me that maybe I could subclass NSArrayController, not
    necessarily an appealing thought (hadn't seen it done anywhere else),
    and Marcus Zarra didn't like it either (thank you).

    So I think the approach is to write your own controller class,
    interact with the configured NSArrayController class, and connect to
    this specific class from the custom view class (perhaps as a
    delegate, although that might be overkill for this simple situation).

    So you have:

    NSView                            NSObject (NSController????)
            ^                                          ^
            |                                          |
    MyView ----------------> MyController ------------------->
    NSArrayController

        mouseDown: ---------> create_point --------------------> newObject
                                                set values

                            (maybe done by setting MyController as a
    delegate)

    Does that look reasonable in the MVC/Cocoa bindings scheme of things?

    Thanks
    Ian

    On 28/05/2007, at 4:01 PM, Ian Joyner wrote:

    > I have a simple app with a view with a mouse down handler. The
    > simple core data model has an entity to track where the user has
    > clicked. The basic architecture I have come up with is to add an
    > outlet to the view for the NSArrayController controlling the point
    > entities. This outlet is connected in IB to the controller. When
    > the view is clicked mouseDown: is called:
    >
    > IBOutlet NSArrayController *nsa;
    >
    > .....
    >
    > -(void) mouseDown: (NSEvent *)event {
    > [nsa insert: self];
    > }
    >
    > Is the view holding a reference to the controller a reasonable
    > architecture? I'm kind of doing what a plus button would do to send
    > add: to the controller to create a new object.
    >
    > If this is OK, the next step is to change the insert to an
    > addObject. Getting code out of the Core Data Programming Guide I'd
    > do something like:
    >
    > -(void) mouseDown: (NSEvent *)event {
    > NSManagedObject *point = [NSEntityDescription
    > insertNewObjectForEntityForName: @"Point" inManagedObjectContext:
    > context]; // Where do I get 'context'?
    > [point setX: event.x]; // pseudo code
    > [point setY: event.y];
    > [nsa addObject: point];
    > }
    >
    > Problem I have with the above is that we are in a view and the
    > managed object context belongs to the document, which the view does
    > not know about the context, which makes me think there is something
    > wrong with this architecture.
    >
    > So is there a better way of creating a managed object when a click
    > is received in a view? Or if this is a legitimate way of doing it,
    > how do I get the right context to insert the managed object into?
    >
    > Thanks
    > Ian Joyner
    > Sportstec
  • On May 30, 2007, at 6:25 PM, Ian Joyner wrote:
    > Reviewing this original question and after some thoughts from Mr
    > Crawford, I think it is more about bindings and the NSController
    > architecture (no surprise there), rather than Core Data.
    > With Cocoa bindings, you just connect up the bindings in IB and
    > messages just get passed to the right things and it works. The great
    > thing about Cocoa bindings is you don't have to write all that messy
    > code that you normally have to in the controller part (thanks to KVC/
    > O). However, what I needed to do was to record something that
    > happened in the view in the CD model entities (this isn't your
    > typical IT app). (It's actually a bit like a game, but user actions
    > are recorded, hence use of CD.)
    >
    Ultimately many views have to do "this sort of thing" -- as noted,
    it's not really specific to Core Data, so the view has to interact
    with "something" to get its job done.  The NSController object is the
    *intermediary* between the view and the model objects, so interacting
    with that should not be considered sacrilege.  Consider the
    GraphicsBindings example at <http://homepage.mac.com/mmalc/CocoaExamples/controllers.html>: both the GraphicsView and the Joystick interact directly with the
    controller...
    Consider also the createGraphicOfClass:withEvent: method in Sketch...

    > I didn't like putting manipulation of a CD entity in the view, but
    > using bindings, the controller bit seemed rather closed off. So the
    > question is how to get controller code into the bindings scheme of
    > things.
    > It occurred to me that maybe I could subclass NSArrayController, not
    > necessarily an appealing thought (hadn't seen it done anywhere
    > else), and Marcus Zarra didn't like it either (thank you).
    >
    I'm not sure what is the impediment to subclassing any of the
    controllers?  You're devolving to them responsibility for managing
    model objects, and if that needs to be customised then the controller
    object is a suitable locus.  Several of my samples at <http://homepage.mac.com/mmalc/CocoaExamples/controllers.html> use subclasses of NSArrayController (for example, the Bookmarks
    example uses the array controller to support drag and drop).  When
    all's said and done, the NSController objects are still *controller*
    objects.  One way of thinking about them (part of the idea behind my
    WWDC session <http://developer.apple.com/wwdc/tracks/macosx.html>) is
    that they represent a re-factoring of common controller patterns so
    that you can leverage reusable components instead of having to re-
    write the glue code for every application.  But this abstraction does
    not mean that they become entirely closed black boxes...

    mmalc
  • On 31/05/2007, at 12:27 PM, mmalc Crawford wrote:

    > On May 30, 2007, at 6:25 PM, Ian Joyner wrote:
    >> Reviewing this original question and after some thoughts from Mr
    >> Crawford, I think it is more about bindings and the NSController
    >> architecture (no surprise there), rather than Core Data.
    >> With Cocoa bindings, you just connect up the bindings in IB and
    >> messages just get passed to the right things and it works. The
    >> great thing about Cocoa bindings is you don't have to write all
    >> that messy code that you normally have to in the controller part
    >> (thanks to KVC/O). However, what I needed to do was to record
    >> something that happened in the view in the CD model entities (this
    >> isn't your typical IT app). (It's actually a bit like a game, but
    >> user actions are recorded, hence use of CD.)
    >>
    > Ultimately many views have to do "this sort of thing" -- as noted,
    > it's not really specific to Core Data, so the view has to interact
    > with "something" to get its job done.  The NSController object is
    > the *intermediary* between the view and the model objects, so
    > interacting with that should not be considered sacrilege.  Consider
    > the GraphicsBindings example at <http://homepage.mac.com/mmalc/
    > CocoaExamples/controllers.html>: both the GraphicsView and the
    > Joystick interact directly with the controller...
    > Consider also the createGraphicOfClass:withEvent: method in Sketch...

    Excellent, I'll study that graphics bindings example closely. Your
    other examples look helpful too.

    >> I didn't like putting manipulation of a CD entity in the view, but
    >> using bindings, the controller bit seemed rather closed off. So
    >> the question is how to get controller code into the bindings
    >> scheme of things.
    >> It occurred to me that maybe I could subclass NSArrayController,
    >> not necessarily an appealing thought (hadn't seen it done anywhere
    >> else), and Marcus Zarra didn't like it either (thank you).
    >>
    > I'm not sure what is the impediment to subclassing any of the
    > controllers?  You're devolving to them responsibility for managing
    > model objects, and if that needs to be customised then the
    > controller object is a suitable locus.  Several of my samples at
    > <http://homepage.mac.com/mmalc/CocoaExamples/controllers.html> use
    > subclasses of NSArrayController (for example, the Bookmarks example
    > uses the array controller to support drag and drop).

    Thanks for answering the question of subclassing NSControllers. That
    sanctions doing a lot (without it being a hack).

    > When all's said and done, the NSController objects are still
    > *controller* objects.  One way of thinking about them (part of the
    > idea behind my WWDC session <http://developer.apple.com/wwdc/tracks/
    > macosx.html>) is that they represent a re-factoring of common
    > controller patterns so that you can leverage reusable components
    > instead of having to re-write the glue code for every application.
    > But this abstraction does not mean that they become entirely closed
    > black boxes...

    I think you've given me the step I need. Thing is Cocoa does such a
    good job of providing most of the code for you, sometimes it's
    difficult to work out where to slot your code in, so that it's not
    something that goes completely against what was intended, which will
    lead to problems later.

    Thanks very much
    Ian
previous month may 2007 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