iOS NSUserDefaults Watching the change of values for a single key
Swift Version:
func setUserDefaultsListener(){
NSUserDefaults.standardUserDefaults().addObserver(self, forKeyPath: "keyPath", options: NSKeyValueObservingOptions.New, context: nil)
}
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if keyPath == "keyPath" {
//Do something
}
}
deinit {
NSUserDefaults.standardUserDefaults().removeObserver(self, forKeyPath: "keyPath")
}
Swift 3 Version:
override func viewDidLoad() {
super.viewDidLoad()
UserDefaults.standard.addObserver(self, forKeyPath: "keyPath", options: .new, context: nil)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "keyPath" {
//Do something
}
}
deinit {
UserDefaults.standard.removeObserver(self, forKeyPath: "keyPath")
}
Edit: viewDidUnload
is now deprecated, use dealloc
instead to removeObserver
This should work perfectly, I have just tested here.
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSUserDefaults standardUserDefaults] addObserver:self
forKeyPath:@"SomeKey"
options:NSKeyValueObservingOptionNew
context:NULL];
// Testing...
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@"test" forKey:@"SomeKey"];
[defaults synchronize];
}
- (void)viewDidUnload
{
[super viewDidUnload];
[[NSUserDefaults standardUserDefaults] removeObserver:self forKeyPath:@"SomeKey"];
}
- (void)observeValueForKeyPath:(NSString *) keyPath ofObject:(id) object change:(NSDictionary *) change context:(void *) context
{
if([keyPath isEqual:@"SomeKey"])
{
NSLog(@"SomeKey change: %@", change);
}
}
Things you could test.
Put a break point in viewDidUnload and make sure the view isn't disappearing on you (since you are changing
SomeKey
from another viewController) If this is the case then maybe move your register/de-register code into init/dealloc depending on how your VC works.Use explicit KeyPath like
@"SomeKey"
not a substitution likeSOME_NSSTRING_VARIABLE