TonyNeallon
TonyNeallon

Reputation: 6607

Clearing NSUserDefaults

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

Answers (15)

Valentin Shergin
Valentin Shergin

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

Hemang
Hemang

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

Jaywant Khedkar
Jaywant Khedkar

Reputation: 6141

Try This, It's working for me .

Single line of code

[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];

Upvotes: 0

Christopher Rogers
Christopher Rogers

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

Adam Waite
Adam Waite

Reputation: 18855

In Swift:

let defaults = NSUserDefaults.standardUserDefaults()
defaults.dictionaryRepresentation().keys.forEach { defaults.removeObjectForKey($0) }

Upvotes: 7

Sohel L.
Sohel L.

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

juliensaad
juliensaad

Reputation: 2059

Here is the answer in Swift:

let appDomain = NSBundle.mainBundle().bundleIdentifier!
NSUserDefaults.standardUserDefaults().removePersistentDomainForName(appDomain)

Upvotes: 30

Daniel Gomez Rico
Daniel Gomez Rico

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

iDevAmit
iDevAmit

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.enter image description here

Upvotes: 2

tmr
tmr

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

markeissler
markeissler

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

folse
folse

Reputation: 1801

NSDictionary *defaultsDictionary = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
for (NSString *key in [defaultsDictionary allKeys]) {
                    [[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
}

Upvotes: 15

Roger Sanoli
Roger Sanoli

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

sbooth
sbooth

Reputation: 16986

Did you try using -removeObjectForKey?

 [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"defunctPreference"];

Upvotes: 97

samvermette
samvermette

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

Related Questions