Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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??

like image 231
smudo78 Avatar asked Jun 03 '12 16:06

smudo78


4 Answers

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);
}
like image 56
auco Avatar answered Sep 21 '22 15:09

auco


There is no data provided in the notification's userInfo dictionary, so it looks like you're out of luck unless you want to keep another copy of the data stored in NSUserDefaults elsewhere and perform a diff on the two dictionaries.

like image 30
Jacob Relkin Avatar answered Sep 19 '22 15:09

Jacob Relkin


Use custom notifications to determine what exactly happened, e.g.:

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:self.event, @"eventObject", nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"newEventCreated" object:nil userInfo:options];

If it is not an option with userDefaults, then just read all user defaults everytime you get your NSUserDefaultsDidChangeNotification notification and compair it with previous ones.

like image 33
Maxim Mikheev Avatar answered Sep 18 '22 15:09

Maxim Mikheev


just add [[NSNotificationCenter defaultCenter] removeObserver:self name:NSUserDefaultsDidChangeNotification object:nil];

to your appDidBecomeActive method and then add

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(settingsChangedListener) name:NSUserDefaultsDidChangeNotification object:nil];

to your applicationDidEnterBackground

then use KVO observer as shown above when in the foreground

like image 37
j2emanue Avatar answered Sep 20 '22 15:09

j2emanue