NSUserDefaultsDidChangeNotification: What's the name Of the Key, that Changed?
Solution 1
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);
}
Solution 2
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.
Solution 3
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
Solution 4
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.
Related videos on Youtube
smudo78
Updated on June 04, 2022Comments
-
smudo78 about 2 years
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??
-
smudo78 about 12 yearsIs there another way, to get the name of the changed key?
-
Jacob Relkin about 12 yearsLike I said, you can keep a clone of the data stored in
NSUserDefaults
elsewhere and compare the two dictionaries to see what changed. -
Itachi over 2 yearsThis doesn't work if the key doesn't follow the variable naming format because it's an invalid keypath.