Reputation: 6607
I'm using +[NSUserDefaults standardUserDefaults]
to store application settings. This consists of roughly a dozen string values. Is it possible to delete these values permanently instead of just setting them to a default value?
Upvotes: 292
Views: 135173
Reputation: 7344
I love extensions when they make the code cleaner:
extension NSUserDefaults {
func clear() {
guard let domainName = NSBundle.mainBundle().bundleIdentifier else {
return
}
self.removePersistentDomainForName(domainName)
}
}
Swift 5
extension UserDefaults {
func clear() {
guard let domainName = Bundle.main.bundleIdentifier else {
return
}
removePersistentDomain(forName: domainName)
synchronize()
}
}
Upvotes: 7
Reputation: 27072
Note: This answer has been updated for Swift too.
What about to have it on one line?
Extending @Christopher Rogers answer – the accepted one.
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
and yes, sometime you may need to synchronize
it,
[[NSUserDefaults standardUserDefaults] synchronize];
I've created a method to do this,
- (void) clearDefaults {
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
[[NSUserDefaults standardUserDefaults] synchronize];
}
Swift?
With swift its even more easy.
extension UserDefaults {
class func clean() {
guard let aValidIdentifier = Bundle.main.bundleIdentifier else { return }
standard.removePersistentDomain(forName: aValidIdentifier)
standard.synchronize()
}
}
And usage:
UserDefaults.clean()
Upvotes: 6
Reputation: 6141
Try This, It's working for me .
Single line of code
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
Upvotes: 0
Reputation: 6809
You can remove the application's persistent domain like this:
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
In Swift 3 and later:
if let bundleID = Bundle.main.bundleIdentifier {
UserDefaults.standard.removePersistentDomain(forName: bundleID)
}
This is similar to the answer by @samvermette but is a little bit cleaner IMO.
Upvotes: 525
Reputation: 18855
In Swift:
let defaults = NSUserDefaults.standardUserDefaults()
defaults.dictionaryRepresentation().keys.forEach { defaults.removeObjectForKey($0) }
Upvotes: 7
Reputation: 9540
It's a bug or whatever but the removePersistentDomainForName
is not working while clearing all the NSUserDefaults
values.
So, better option is that to reset the PersistentDomain
and that you can do via following way:
NSUserDefaults.standardUserDefaults().setPersistentDomain(["":""], forName: NSBundle.mainBundle().bundleIdentifier!)
Upvotes: 2
Reputation: 2059
Here is the answer in Swift:
let appDomain = NSBundle.mainBundle().bundleIdentifier!
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(appDomain)
Upvotes: 30
Reputation: 15945
I found this:
osascript -e 'tell application "iOS Simulator" to quit'
xcrun simctl list devices | grep -v '^[-=]' | cut -d "(" -f2 | cut -d ")" -f1 | xargs -I {} xcrun simctl erase "{}"
Source: https://gist.github.com/ZevEisenberg/5a172662cb576872d1ab
Upvotes: 5
Reputation: 1578
All above answers are very relevant, but if someone still unable to reset the userdefaults for deleted app, then you can reset the content settings of you simulator, and it will work.
Upvotes: 2
Reputation: 1530
if the application setting needing reset is nsuserdefault for access to microphone (my case), a simple solution is answer from Anthony McCormick (Iphone - How to enable application access to media on the device? - ALAssetsLibraryErrorDomain Code=-3312 "Global denied access").
on the device, go to Settings>General>Reset>Reset Location Warnings
Upvotes: 0
Reputation: 659
Expanding on @folse's answer... I believe a more correct implementation would be...
NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
NSDictionary *defaultsDictionary = [[NSUserDefaults standardUserDefaults] persistentDomainForName: appDomain];
for (NSString *key in [defaultsDictionary allKeys]) {
NSLog(@"removing user pref for %@", key);
[[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
}
...calling NSUserDefault's persistentDomainForName: method. As the docs state, the method "Returns a dictionary containing the keys and values in the specified persistent domain." Calling dictionaryRepresentation: instead, will return a dictionary that will likely include other settings as it applies to a wider scope.
If you need to filter out any of the values that are to be reset, then iterating over the keys is the way to do it. Obviously, if you want to just nuke all of the prefs for the app without regard, then one of the other methods posted above is the most efficient.
Upvotes: 1
Reputation: 1801
NSDictionary *defaultsDictionary = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
for (NSString *key in [defaultsDictionary allKeys]) {
[[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
}
Upvotes: 15
Reputation: 753
If you need it while developing, you can also reset your simulator, deleting all the NSUserDefaults
.
iOS Simulator -> Reset Content and Settings...
Bear in mind that it will also delete all the apps and files on simulator.
Upvotes: 29
Reputation: 16986
Did you try using -removeObjectForKey
?
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"defunctPreference"];
Upvotes: 97
Reputation: 40437
This code resets the defaults to the registration domain:
[[NSUserDefaults standardUserDefaults] setPersistentDomain:[NSDictionary dictionary] forName:[[NSBundle mainBundle] bundleIdentifier]];
In other words, it removeObjectForKey
for every single key you ever registered in that app.
Credits to Ken Thomases on this Apple Developer Forums thread.
Upvotes: 103