iosobjective-cnsuserdefaultsnsnotificationcenter

NSUserDefaultsDidChangeNotification: What's the name Of the Key, that Changed?


This code will call the method "defaultsChanged", when some value in UserDefaults changed

NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self
           selector:@selector(defaultsChanged:)  
               name:NSUserDefaultsDidChangeNotification
             object:nil];

This Code will give me the VALUE that changed

- (void)defaultsChanged:(NSNotification *)notification {
    // Get the user defaults
    NSUserDefaults *defaults = (NSUserDefaults *)[notification object];

    // Do something with it
    NSLog(@"%@", [defaults objectForKey:@"nameOfThingIAmInterestedIn"]);
}

but how can I get the NAME of the key, that changed??


Solution

  • As others stated, there is no way to get the info about the changed key from the NSUserDefaultsDidChange Notification. But there is no need to duplicate any content and check for yourself, because there is Key Value Observing (KVO) which also works with the NSUserDefaults, if you need to specifically be notified of a certain property:

    First, register for KVO instead of using the NotificationCenter:

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults addObserver:self
               forKeyPath:@"nameOfThingIAmInterestedIn"
                  options:NSKeyValueObservingOptionNew
                  context:NULL];
    

    don't forget to remove the observation (e.g. in viewDidUnload or dealloc)

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults removeObserver:self forKeyPath:@"nameOfThingIAmInterestedIn"];
    

    and finally implement this method to receive KVO notifications

    -(void)observeValueForKeyPath:(NSString *)keyPath 
                     ofObject:(id)object
                       change:(NSDictionary *)change
                      context:(void *)context 
    {
        NSLog(@"KVO: %@ changed property %@ to value %@", object, keyPath, change);
    }