I have a non document-based Core Data application. There's an NSTreeController
that manages a collection of objects displayed in a single NSOutlineView
as a source list. They are the usual kinds of things: headings, folders, smart folders, etc.
Each of these container objects has a collection of contents
objects. I have three separate view controllers that display these objects in various ways (an NSTableView
and two custom graphical views, if you really want to know) But these are really just three different presentations of the same data. They should always show the same objects, share the same selection, etc.
I'm also using a hierarchy of NSViewController
s to manage my views. (If I'd known about Cathy Shive's excellent KTUIKit
at the time, I would have used that, but my view controllers are very similar to -- and very much inspired by -- hers)
As it stands now, I have an NSTreeController
living in the view controller for the source list view. I also have an NSArrayController
in each of the sub-view controllers which is bound to the NSTreeController
via some overly-complicated keypaths.
So, what needs to change, in my opinion, is the following:
NSTreeController
needs to move out of the outline view's controller.NSArrayController
that each of the contents views can be bound to instead of three separate ones. Although I'm less certain of this point.What I'm having difficulty with is figuring out where these things should live. I'm having a hard time deciding which objects, if any, truly "own" the various controllers. Do the parent view controllers own it? Does the window controller? As this is application-level data, do I go so far as to make these owned by the App Delegate? (I could imagine a circumstance where a use might want to open multiple windows, although that's not currently supported) What does the StackOverflow hive mind think?
NSArrayController and NSTreeController are treated more as view objects than true controllers, so it sounds like you're on the right track. I would have started about the same way you did, giving each NSViewController its own NSArrayController or NSTreeController as needed, and configuring the bindings between them at runtime through the window controller that's responsible for putting all the pieces together.
If you think it would simplify things, it doesn't sound like there would be anything wrong with moving the NSArrayController and NSTreeController objects to the window controller. You could still set up bindings to the view controller's representedObject in IB, and then create the array/tree controllers in code in your window controller at the appropriate time. Just be carefully to not get too complicated here. I've found that when you have a lot of view controllers in the same window using representedObject for different things, it's easier to create separate, typed properties so you can understand what parts go where.
I don't really understand the benefit of making the array/tree controllers part of the app delegate, but I don't know much about what you're doing there. Maybe you would benefit from making your own "data controller" object?
Questions like this can be difficult to decide upon since sometimes there's no "right" answer, but as long as you keep simplicity and understandability in mind you'll be okay. Don't be afraid to pick a plan and move on, you can always refactor later... I know there have been times when I've spent days on architecture questions like this, when I could have been working on something more practical!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With