I have an entity 'person' and a 1-m related entity 'visit' defined in CoreData. Now I want to display and modify their values in related tables using NSArray controllers with COCOA bindings on MacOS
My project is for MacOS and I'm using Xcode with Swift. I have defined the data structure and Viewcontroller objects using the Xcode builder. The table for the 'person' is already working and I can add or delete persons. However I'm not able to find a way to bind the 'visit' table to the selected person. I tried several options, like connecting the content of the 'visit' array controller as recommended in Master-detail using bindings with TWO NSTableViews, but all ended up in compile time errors.
As I'm working with the visual Xcode builders, the is not much code for the moment. Here is what I did so far:
I have defined the two entity classes with the Xcode data model builder, then the two tables and array controllers with the storyboard interface builder. Then I bound the table views content to the respective array controllers and the columns to their own table view with the respective entity attribute. I also added + and - buttons to add some rows. So far everything worked fine. But the details ('visit') had no connection to any 'person'. Hence I deleted all entries in the 'visit' table and tried to bind the content of its array controller to the selected person. That is where I get stuck. Maybe I missed some initialization of the CoreData entities, but I have no clue how to proceed
I'm looking at my working macOS project which has two NSTableViews in Master-Detail.
MasterAC.selection.details
, where details
is the name of the master-to-detail relationship.If that does not fix it, I can poke around some more. Cocoa Bindings with Core Data in macOS are beautiful once you get them working :))
If the master-to-detail to-many relationship is an unordered set, and you are using the old school method of defining an index
attribute on your Detail entity, you can define a detailsOrdered
attribute in your Master class like this:
func detailsOrdered() -> [Any]? {
return details().arraySorted(byKeyPath: "index")
}
and then bind to MasterAC.selection.detailsOrdered
instead of MasterAC.selection.details
.
The above implementation requires the following extension of Set:
extension Set<AnyHashable> {
func arraySorted(byKeyPath keyPath: String?) -> [Any]? {
let unorderedArray = Array(self)
let sortDescriptor = NSSortDescriptor(key: keyPath, ascending: true)
let orderedArray = (unorderedArray as NSArray).sortedArray(using: [sortDescriptor])
return orderedArray
}
}