0

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

vomi
  • 993
  • 8
  • 18
  • What is "saves" and what are the "other fields"? Are `note` and `customFields` KVO compliant? Please post a [mve]. – Willeke Nov 20 '19 at 14:37
  • `Note` is a NSManagedObject. `customFields` is a `NSMutableDictionary` instance, so KVO-compliant by default. The `save()` is basically a `NSManagedObjectContext.save()`. The other fields in `Note` are Strings, NSNumbers, ... (various NSManagedObject properties). – vomi Nov 20 '19 at 18:05
  • Did the text field end editing? – Willeke Nov 20 '19 at 19:17
  • Yes it is, I verified :/ – vomi Nov 20 '19 at 19:57

1 Answers1

0

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!

vomi
  • 993
  • 8
  • 18