Search code examples
objective-ccocoacore-datacocoa-bindingsnsarraycontroller

setFilterPredicate on a NSArrayController doesn't work if it's in "Auto Rearrange Content"


I have a classic CoreData application, displaying it's data in NSTableView with Binding (all done with XCode 4.2).

Working fine until I decide yesterday to check, in Attributes Inspector, the 'Auto Rearrange Content' for the ArrayController. Now, when I try to set the filter predicate on it, I get:

[<_NSFaultingMutableSet 0x102b65950> addObserver:forKeyPath:options:context:] is not supported. Key path: name

Keep in mind that without this option it work perfectly: the predicate is good and the controller is properly filtering it's managed content, and the table view is displaying only the entity that match the predicate.

Of course I could just de-enable this "auto rearrange content" but it is useful for maintaining the sort order in the event of a change in entities. If I edit one entity, the "date modified" change, and since my sort order is on this date I want the TableView to re-order it's line automatically. And it does with this option, but alas with added bug of "addObserver not supported".

The _NSFaultingMutableSet come from a to-many relationship in the concerned entity, hence the "Set". Maybe "Auto Rearrange Content" isn't compatible with "setFilterPredicate" with a to-many relationship ?

Anybody having similar problem ? An internal bug of NSArrayController ?

Note: the predicates that cause problem are of the form

name CONTAINS[cd] %@ OR ANY aliases.name CONTAINS[cd] %@

or

ANY tags.name CONTAINS[cd] %@ OR ANY tags.aliases.name CONTAINS[cd] %@

it's seems that the 'ANY' is causing some conflict...


Solution

  • Found a solution, with the above comment on SUBQUERY.

    Keep the option 'auto rearrange content' but change the predicate to:

    name CONTAINS[cd] %@ OR SUBQUERY(aliases, $anAlias, $anAlias.name CONTAINS[cd] %@).@count != 0
    

    and

    SUBQUERY(tags, $aTag, $aTag.name CONTAINS[cd] %@).@count !=0 OR SUBQUERY(tags, $aTag, $aTag.aliases.name CONTAINS[cd] %@).@count !=0
    

    Respectively.

    Probably the predicate were wrong, I just didn't run into others problems before.