0

Model

extension MyEntity {

    @nonobjc public class func fetchRequest() -> NSFetchRequest< MyEntity > {
        return NSFetchRequest< MyEntity >(entityName: "MyEntity")
    }

    @NSManaged public var customFields: NSDictionary?
}

customFields keys and values are Strings.

Bindings

Columns are created in code since the user can add/remove columns.

column.bind(NSBindingName.value, to: treeController!, withKeyPath: "arrangedObjects.customFields.\(uniqueID))", options: [.createsSortDescriptor:false])
column.sortDescriptorPrototype = NSSortDescriptor(key: "customFields.\(uniqueID))", ascending: true, selector: #selector(NSString.compare(_:)))

Issue

Sorting will not work when clicking on column header. Values are simply String, but it seems they are not considered as such. Any idea of where the problem might be? Thanks!

UPDATE

  • The NSTreeController is in Entity mode
  • This is a view-based outline view (is the cell-based still used nowadays??)
  • For static columns (defined in IB), sorting works
  • When I sort on dynamic columns, nothing happens (no error)
  • I suppose that the values are not considered as string because it is a NSDictionary that does not use generics

UPDATE 2

On another project, I successfully managed to do so. The only difference is that the dictionary is not , but where MyObject has a value property of type String. The sorting is enabled using the following code:

/* Bind column for sorting */
column.bind(NSBindingName.value, to: resultsArrayController!, withKeyPath: "arrangedObjects.dictionary.\(String(describing: paramDef.objectID)).value", options: nil)

or this works as well:

column.sortDescriptorPrototype = NSSortDescriptor(key: "dictionary.\(String(describing: paramDef.objectID)).value", ascending: true, selector: #selector(NSString.compare(_:)))

I do not know why it works in that case and not above.

vomi
  • 993
  • 8
  • 18
  • Does this answer your question? [Sorting NSTableColumn contents](https://stackoverflow.com/questions/2398481/sorting-nstablecolumn-contents) – El Tomato Jan 04 '20 at 10:34
  • Is the tree controller in entiry mode? Is this a cell based outline view or a view based outline view? What happens if you let the value binding create the sort descriptor? Why do you think the values are not considered strings? Is "Sorting will not work" the same as "nothing happens" or do you get an error or exception? – Willeke Jan 04 '20 at 11:05
  • @ElTomato, thanks but no it does not answer my question. I use bindings with a NSTreeController – vomi Jan 04 '20 at 14:08
  • @Willeke, I updated the question with the extra information. – vomi Jan 04 '20 at 14:09
  • 1
    What is your goal here? How do you sort using a dictionary, it is not obvious what makes one dictionary come before another so you need to define it. This looks really complicated, maybe you could denormalise your entity and have an attribute on your entity that is a copy of whatever key and/or value from your dictionary you want to sort on and instead sort on this new attribute – Joakim Danielson Jan 04 '20 at 14:40
  • customFields contains string values, with the key being the unique ID of the column. I simply want to sort on the string values for each column. – vomi Jan 04 '20 at 14:48
  • The column binding is for use with cell based table/outline views only. Did you bind the value of the static columns? Which properties of the outline view did you bind to the tree controller? Is "Sorting will not work" the same as "nothing happens"? Any runtime errors or exceptions? – Willeke Jan 04 '20 at 16:12
  • Added a second update with extra information. – vomi Jan 06 '20 at 09:25
  • The compare function always return `orderedSame`. Any way I can see from which class the compare function is called ? – vomi Jan 06 '20 at 15:27

1 Answers1

0

OK this was very stupid. A typical KVO typo:

key: "customFields.\(uniqueID))" should be: key: "customFields.\(uniqueID)"

There was an extra parenthesis. I feel stupid... This works perfectly now...

vomi
  • 993
  • 8
  • 18