1

I have been looking into how to populate a Source List from core data using multiple entities. If I had one entity, I can follow documentation and use a NSTreeController to populate and bind my data to the NSOutlineView.

In my specific situation I have around 3 hard-coded groups, where each one of my groups would relate to a separate core data entity. I attempted to combine them but they all have relationships to different entities so I wouldn't be able to combine them all in one core data entity. I ideally wanted to bind my 3 core data entities to my Source List where they look something like the following (Where Pens, Papers and Desks are all separate entities) :

enter image description here

Does anyone know of anyway I'd be able to use a controller to help mange and combine three entities with my Source List or would the best approach be to manually populate NSOutlineView? Can I use some sort of array of NSArrayControllers to populate my NSOutlineView? Is there a way I can override NSTreeController to take in data from three sources?

Andre Yonadam
  • 964
  • 1
  • 13
  • 30
  • 1
    Have you tried `NSOutlineViewDataSource`? I wonder since you seem to know the limitations of bindings. – Fabian Aug 12 '18 at 20:32
  • @Purpose I have looked at 'NSOutlineViewDataSource' which is needed to populate an NSOutlineView with or without Core Data. However, at this point I'm wondering if I should just do it all manually using a conventional data source rather than a controller. – Andre Yonadam Aug 12 '18 at 22:07
  • I won‘t tell you what you should do. But I tell you that `NSOutlineViewDataSource` does not have the limitations NSTreeController and NSArrayController have. – Fabian Aug 12 '18 at 22:12
  • @Purpose Thank you very much for your input. I might end up going with NSOutlineViewDataSource then since there is no built in way to do what I was originally looking for with bindings then. – Andre Yonadam Aug 12 '18 at 22:24
  • 1
    You can use `NSTreeController` but you have to provide the contents. – Willeke Aug 12 '18 at 22:25
  • 1
    @Willeke When would you use NSTreeController and when NSOutlineViewDataSource then if both fit the case? Is it just a difference in API where in one you have to check which type it is and then act accordingly and in the other you implement child, isItemExtendable and numberOfChildren directly in each type? – Fabian Aug 12 '18 at 22:36
  • @Willeke when you say "provide the contents" do you mean that I have to manually populate the NSTreeController instead of binding it to Core Data. If so, would it be possible to add parent nodes manually then bind their children to a NSArrayController, one for each entity, and bind those? – Andre Yonadam Aug 12 '18 at 22:50
  • The tree controller is in Class mode and doesn't fetch. The contents is an array of 3 objects: Pens, Papers and Desks. These objects must be KVO compliant for the children keypath. Do all entites have the same title key and can you bind the cells? – Willeke Aug 13 '18 at 00:06
  • @Willeke Yes in this case they would have same same title key but they would all be different entities. Due to each entity having its own unique relationships, they (Pens, Papers and Desks) can't be merged to all be a part of one entity. – Andre Yonadam Aug 13 '18 at 03:24
  • `NSTreeController` or `NSOutlineViewDataSource` is a matter of taste. In both cases you have to provide the data and watch mutations. – Willeke Aug 13 '18 at 10:52

1 Answers1

0

As an experiment I created a project with an outline view and tree controller. The contents of the tree controller is an array of dictionary, the array controllers (in entity mode) are outlets:

treeController.content = [
    ["arrayController": penTreeArrayController, "name": "Pens"],
    ["arrayController": paperTreeArrayController, "name": "Papers"],
    ["arrayController": deskTreeArrayController, "name": "Desks"]
]

The tree controller is a subclass of NSTreeController:

override func childrenKeyPath(for node: NSTreeNode) -> String? {
    if node.representedObject is NSManagedObject {
        return nil
    }
    return "arrayController.arrangedObjects"
}

It seems to work. When I add or remove a pen, the outline view automagically updates. It doesn't work the other way around, I can't use the tree controller to add a pen.

Willeke
  • 14,578
  • 4
  • 19
  • 47