Reputation: 1291
I have switches and I want to detect if any of switch was changed position, if changes was made I need to start my action.
Switches stores position in NSUserDefaults
- (IBAction)saveSwitch:(id)sender
{
NSUserDefaults *defs1 = [NSUserDefaults standardUserDefaults];
[defs1 setBool: blackSwitch.on forKey: @"blackKey"];
NSUserDefaults *defs2 = [NSUserDefaults standardUserDefaults];
[defs2 setBool: greenSwitch.on forKey: @"greenKey"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
Upvotes: 1
Views: 4528
Reputation: 15566
The best way to track changes to NSUserDefaults
is to add an observer using KVO. This way you do not need to perform any custom notification code or track changes manually.
In the class that wants to be informed about the changes just register it as a listener to the specified keys:
[[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:@"blackKey" options:NSKeyValueObservingOptionNew context:nil];
[[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:@"greenKey" options:NSKeyValueObservingOptionNew context:nil];
Then just respond to the notification:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (object == defaults) {
// Here you can grab the values or just respond to it with an action.
}
}
Now whenever one of those keys changes you will be notified automatically.
This is a super clean solution and allows for some heavy reuse. For example, if you add the NSKeyValueObservingOptionInitial
key to the options
parameter above (NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
) then it will also notify your observer method with the initial value, allowing you to reuse that method even for initial states.
Swift Version
Setting up the defaults:
NSUserDefaults.standardUserDefaults().addObserver(self, forKeyPath: "blackKey", options: .New, context: nil)
NSUserDefaults.standardUserDefaults().addObserver(self, forKeyPath: "greenKey", options: .New, context: nil)
The observer:
override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {
if object is NSUserDefaults {
// Here you can grab the values or just respond to it with an action.
}
}
Upvotes: 2
Reputation: 4990
If you're using NSUserDefaults the easiest is to subscribe NSUserDefaultsDidChangeNotification. It is automatically sent when something changes.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appSettingsDidChange:)
name:NSUserDefaultsDidChangeNotification
object:nil];
Upvotes: 4
Reputation: 1162
You can post a notification whenever you call synchronize
[[NSNotificationCenter defaultCenter] postNotificationName:@"MyAppSettingsChanged" object:self userInfo:nil];
Then in your other class listen to the notification.
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onAppSettingsChanged:) name:@"MyAppSettingsChanged" object:nil];
-(void) onAppSettingsChanged:(NSNotification)notification
{
// settings changed
}
If you want, you can pass an NSDictionary
into userInfo when calling postNotificationName
that contains information like which settings have changed.
Upvotes: 5
Reputation: 4977
You cannot detect changes in NSUserDefaults. Instead, track when the switch itself is changed, and handle that event. Example:
[blackSwitch addTarget:self
action:@selector(blackSwitchChanged:)
forControlEvents:UIControlEventValueChanged];
Handle the switch position changing:
- (IBAction)blackSwitchChanged:(id)sender {
NSLog(@"Black switch changed");
..
// check if blackSwitch is on or off.
}
Upvotes: 0