Cocoa bindings only working one way (NSMutableDictionary)

77 Views Asked by At

I have a ViewController with a 'Note' object as an instance variable. This variable is set before the ViewController appears.

The Note object contains a customFields NSMutableDictionary<String, String>. I bind each value of the dictionary to a NSTextField of the dictionary in viewWillAppear :

newTextField.bind(.value, to: self, withKeyPath: "note.customFields.\(key)", options: nil)

The textField correctly displays the value from note.customFields.\(key). BUT, if the user edits that value and saves, the change is not reflected in the dictionary. The save() (basically a managedobjectcontext.save()) method has been tested with other fields (bound to other non-dictionary instance variables) and works properly.

Is there a reason why the dictionary does not receive the updated value?

Thanks for the help :-)

EDIT: here is the definition of customFields in the model:

enter image description here

1

There are 1 best solutions below

0
vomi On

The issue here is the combination of mutable type (here NSMutableDictionary) and Core Data.

This post helped: Core Data not saving transformable NSMutableDictionary

And this article helped as well: https://medium.com/@rohanbhale/hazards-of-using-mutable-types-as-transformable-attributes-in-core-data-2c95cdc27088

Solution summary

As proposed in the first link up-mentioned, I tried informing Core Data of changes in my NSMutableDictionary using note.valueDidChange(forKey: "customFields") but it did not work properly.

So I ended up using the second proposition in the first link, which is the same as the solution proposed in the second linked:

  • Use a NSDictionary as transformable type
  • When you need to modify this dictionary, use mutableDict = dictionary.mutableCopy(), and then save back to the nsdictionary : dictionary = mutableDict.copy()
  • For the specific case of NSTextField binding, the bindings will work for displaying the value, but for updating the value, you have to do it without bindings (whenever your view will disappear or when textfield ends editing)

Hope that helps!