79

I use the NSUserDefaults dictionary to store basic information such as high scores etc so that when the user closes the app data is not lost. Anyways I use:

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];

to store data. If I wish to store a new high score for example then I would do:

[prefs setInteger:1023 forKey:@"highScore"];
[prefs synchronize];  //this is needed in case the app is closed. 

and later if I wish to retrieve the high score I would do:

[prefs integerForKey:@"highScore"];

anyways the point is that I store a lot of other things because the NSUserDefaults enable you to store booleans, integers, objects etc. what method would I have to execute to delete all keys so that NSUserDefaults becomes like the fist time I launch the app?

I am looking for something like:

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs deleteAllKeysAndObjectsInTheDictionary];

or maybe there is a way of getting all keys and I have to loop through each object but I don't know how to remove them.

EDIT:

I have tried :

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[NSUserDefaults resetStandardUserDefaults];
[prefs synchronize];

and I still am able to retrieve a high score....

Sourabh Sharma
  • 8,222
  • 5
  • 68
  • 78
Tono Nam
  • 34,064
  • 78
  • 298
  • 470
  • See this related Question, [Delete all my NSUserDefaults that start with a certain word](http://stackoverflow.com/q/3436792/642706), with a [good answer about using a NSPredicate](http://stackoverflow.com/a/3436840/642706) to find certain entries in NSUserDefaults. – Basil Bourque Jun 19 '14 at 23:57

18 Answers18

151

If you have a look at the NSUserDefaults documentation you will see a method - (NSDictionary *) dictionaryRepresentation. Using this method on the standard user defaults, you can get a list of all keys in the user defaults. You can then use this to clear the user defaults:

- (void)resetDefaults {
    NSUserDefaults * defs = [NSUserDefaults standardUserDefaults];
    NSDictionary * dict = [defs dictionaryRepresentation];
    for (id key in dict) {
        [defs removeObjectForKey:key];
    }
    [defs synchronize];
}
Alex Nichol
  • 7,512
  • 4
  • 32
  • 30
  • 22
    Shortest way to do this with the same results:`______________________________________________` `NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];` `__________________` `[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain]; ` – skywinder Oct 04 '13 at 09:18
  • 13
    This is not the best way of doing it since it will iterate and attempt to remove *all* user defaults keys including the system ones instead of just the app ones. Using -removePersistentDomainForName: as suggested in the other answer is much better. – Pol Feb 21 '14 at 21:00
  • 1
    Wouldn't it make more sense to use [dict removeAllObjects] instead of looping over the whole dictionary? – Fitter Man Nov 16 '14 at 23:01
  • @FitterMan no, that only removes objects from the dictionary, not from `NSUserDefaults`… – mxcl Jun 06 '17 at 19:35
75

Shortest way to do this with the same results like in Alex Nichol's top answer:

NSString *appDomain = NSBundle.mainBundle.bundleIdentifier;
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
[[NSUserDefaults standardUserDefaults] synchronize];
Iulian Onofrei
  • 9,188
  • 10
  • 67
  • 113
skywinder
  • 21,291
  • 15
  • 93
  • 123
  • 1
    How to clear NSUserDefaults alloc]initWithSuiteName. – Durgaprasad Jun 03 '16 at 10:18
  • 1
    Don't forget to `synchronize` your NSUserDefaults right after if you are using defaults in a way that will require that. – Albert Renshaw Nov 25 '17 at 05:30
  • Note that KVO observers won't be notified when removing a complete domain (though a notification is posted). For KVO compatibility it's probably better to iterate through each key returned from `persistentDomainForName` and remove it with `removeObjectForKey`. – bcause Nov 27 '19 at 21:47
45

One-liner:

[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:NSBundle.mainBundle.bundleIdentifier];
Iulian Onofrei
  • 9,188
  • 10
  • 67
  • 113
Cameron E
  • 1,839
  • 1
  • 19
  • 20
33

Simple Solution

Objective C:

NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];

Swift 3.0 to Swift 5.0 :

if let appDomain = Bundle.main.bundleIdentifier {
    UserDefaults.standard.removePersistentDomain(forName: appDomain)
}
Sourabh Sharma
  • 8,222
  • 5
  • 68
  • 78
16

+ (void) resetStandardUserDefaults doesn't persist the changes, it simply resets the in-memory user defaults object so that the next synchronize call will read from the on-disk copy, instead of overwriting existing in-memory values with the on-disk versions.

Iterating over the keys is better, but there's actually a function that does this for you: removePersistentDomainForName:.

// you can usually get the domain via [[NSBundle mainBundle] bundleIdentifier]
[[NSUserDefaults standardUserDefaults]
 removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
// or use a string for any other settings domains you use
//[[NSUserDefaults standardUserDefaults]
// removePersistentDomainForName:@"com.mycompany.myappname"];
[[NSUserDefaults standardUserDefaults] synchronize];

At the end of the synchronize operation, both the disk and memory copies of user defaults will contain none of the values set by your application.

16

Swift version:

if let bid = NSBundle.mainBundle().bundleIdentifier {
    NSUserDefaults.standardUserDefaults().removePersistentDomainForName(bid)
}   
superarts.org
  • 7,009
  • 1
  • 58
  • 44
11

Oneliner in Swift:

Swift 3

NSUserDefaults.standardUserDefaults().removePersistentDomainForName(
NSBundle.mainBundle().bundleIdentifier!)

Swift 4

UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!)
netshark1000
  • 7,245
  • 9
  • 59
  • 116
  • Swift 4.0 ----- UserDefaults.standard.removePersistentDomain(forName: Bundle.main.bundleIdentifier!) UserDefaults.standard.synchronize() – uplearned.com Sep 19 '17 at 13:48
  • @GerardGrundy You don't need `.synchronize()`. You never do in such normal situations. Contents are automatically saved. – Eric Aya Sep 19 '17 at 14:01
  • @Moritz Though if the app shut down before it had time to automatically save then you would need to force save. – uplearned.com Sep 21 '17 at 22:57
  • Also, `synchronize` is not just "save". `synchronize` saves *and* loads the whole defaults object (which can be bigger than expected). It is never necessary to call `synchronize` in order to "save" defaults. If you call it, you must have a good reason, and those are rare. ;) – Eric Aya Sep 22 '17 at 07:34
10

For those of you that want to do this in the test target, use this (as the removePersistentDomain does not work for that case)

Swift 3:

for key in Array(UserDefaults.standard.dictionaryRepresentation().keys) {
     UserDefaults.standard.removeObject(forKey: key)
}
bogen
  • 9,954
  • 9
  • 50
  • 89
5

For Swift 3:

let appDomain = Bundle.main.bundleIdentifier!
UserDefaults.standard.removePersistentDomain(forName: appDomain)
Taichi Kato
  • 602
  • 9
  • 24
5

For Swift 3:

if let bundle = Bundle.main.bundleIdentifier {
    UserDefaults.standard.removePersistentDomain(forName: bundle)
}
Jay Mehta
  • 1,511
  • 15
  • 20
2

Swift

func resetUserDefaults(){
  let userDefaults = NSUserDefaults.standardUserDefaults()
  let dict = userDefaults.dictionaryRepresentation() as NSDictionary
        
  for key in dict.allKeys {
    userDefaults.removeObjectForKey(key as! String)
  }
        
  userDefaults.synchronize()      
}
aturan23
  • 4,798
  • 4
  • 28
  • 52
Dhananjay Patil
  • 442
  • 3
  • 10
2

Swift
place in your logic

if let appDomain = Bundle.main.bundleIdentifier {
  UserDefaults.standard.removePersistentDomain(forName: appDomain)
}
aturan23
  • 4,798
  • 4
  • 28
  • 52
Sai kumar Reddy
  • 1,751
  • 20
  • 23
2

I found it the most handy to place the code in an extension on UserDefaults.

Swift 5

extension UserDefaults {
    static func clear() {
        guard let domain = Bundle.main.bundleIdentifier else { return }
        UserDefaults.standard.removePersistentDomain(forName: domain)
        UserDefaults.standard.synchronize()
    }
}

Usage

UserDefaults.clear()
Iron John Bonney
  • 2,451
  • 1
  • 17
  • 14
1

Swift 3 or 4 We can even simplify described snippet into this modern expression:

func clearAll() {
    let settingsDictionary = userDefaults.dictionaryRepresentation()
    settingsDictionary.forEach { key, _ in userDefaults.removeObject(forKey: key) }
    userDefaults.synchronize()
}
1

Does this method not do that:

+ (void)resetStandardUserDefaults

From the documentation for NSUserDefaults:

resetStandardUserDefaults

Synchronizes any changes made to the shared user defaults object and releases it from memory.

+ (void)resetStandardUserDefaults

Discussion

A subsequent invocation of standardUserDefaults creates a new shared user defaults object with the standard search list.

Based on this, you can do:

[NSUserDefaults resetStandardUserDefaults];
[NSUserDefaults standardUserDefaults];

and now the defaults should be reset.

PengOne
  • 48,188
  • 17
  • 130
  • 149
  • when I call [NSUserDefaults resetStandardUserDefaults]; it does not delete anything. – Tono Nam Jul 22 '11 at 23:26
  • It is my understanding that this relates to the standardUserDefaults shared object rather than the information stored on disk, meaning that this would have no noticeable effect on the saved user defaults. – Alex Nichol Jul 22 '11 at 23:26
  • 1
    @Tono: when you call `[NSUserDefaults resetStandardUserDefaults];` and *then* do `NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];`, my understanding (which may be incorrect) is that `prefs` will be a blank slate once again. – PengOne Jul 22 '11 at 23:28
  • @Alex: Yes, it's the same idea. I hadn't read your answer yet since I was engaged in discussion on mine. I'll remove the edit and defer to you for that approach. – PengOne Jul 22 '11 at 23:36
0

To remove all UserDefault value in swift (Latest syntax)

//remove UserDefaults
if let identifier = Bundle.main.bundleIdentifier {
  UserDefaults.standard.removePersistentDomain(forName: identifier)
  UserDefaults.standard.synchronize()
}
aturan23
  • 4,798
  • 4
  • 28
  • 52
Hardik Thakkar
  • 15,269
  • 2
  • 94
  • 81
0

In Swift 5.0 below single line of code is enough.

UserDefaults.standard.dictionaryRepresentation().keys.forEach(defaults.removeObject(forKey:))
Naresh
  • 16,698
  • 6
  • 112
  • 113
-1

I use this:

UserDefaults.standard.removeAll()
Mahdi Moqadasi
  • 2,029
  • 4
  • 26
  • 52