3

I want to observe the value stored in UserDefaults.standard under the key: com.apple.configuration.managed, so I did this:

UserDefaults.standard.addObserver(self, forKeyPath: "com.apple.configuration.managed", options: [.new, .old], context: nil)

I then implemented this:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {

}

When I run the app observeValue... is never called when that default is changed, instead Xcode crashes with this error:

*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ addObserver: forKeyPath:@"com.apple.configuration.managed" options:1 context:0x0] was sent to an object that is not KVC-compliant for the "com" property.'

What's the right way of observing com.apple.configuration.managed in the UserDefaults.standard?

zumzum
  • 17,984
  • 26
  • 111
  • 172
  • 1
    This is not a duplicate of [Detect changes on NSUserDefaults](https://stackoverflow.com/questions/15202562/detect-changes-on-nsuserdefaults). The problem here is the dots in the key path, which that question doesn't address. – rob mayoff Jul 27 '17 at 01:38
  • I guess this https://stackoverflow.com/a/14172860/728246 could make my question seem like a duplicate, I just didn't realize the "." was the cause of this error... – zumzum Jul 27 '17 at 03:21
  • The root cause of the problem is the same, but `NSUserDefaults` is KVO-compliant whilst `NSDictionary` is not, so I don't think closing as a duplicate is necessary. – rob mayoff Jul 27 '17 at 03:51

1 Answers1

4

You can use KVC observing to observe properties of an object, and you can use KVC observing to observe the values that you assign to UserDefaults, but you cannot use KVC to observe a value where the value identifier contains periods, since this is used to describe a hierarchical keypath.

So, the exception message is correct, UserDefaults is not KVC compliant for the com property; what you have asked is to be notified when the managed property of the object referred to by the configuration property of the object referred to by the apple property of the object referred to by the com property of the UserDefaults object is modified.

So you can use KVC to be notified when "MyDefault" changes but not when "My.Default" changes. If you can't change the name of your user default then you will need to observe the NSUserDefaultsDidChangeNotification Notification

Paulw11
  • 108,386
  • 14
  • 159
  • 186