73

I have this code to remove all UserDefaults data from the app:

let domain = Bundle.main.bundleIdentifier!
UserDefaults.standard.removePersistentDomain(forName: domain)

print(Array(UserDefaults.standard.dictionaryRepresentation().keys).count)

But I got 10 from the print line. Shouldn't it be 0?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Zizoo
  • 1,694
  • 5
  • 20
  • 42

2 Answers2

129

The problem is you are printing the UserDefaults contents, right after clearing them, but you are not manually synchronizing them.

let domain = Bundle.main.bundleIdentifier!
UserDefaults.standard.removePersistentDomain(forName: domain)
UserDefaults.standard.synchronize()
print(Array(UserDefaults.standard.dictionaryRepresentation().keys).count)

This should do the trick.

Now you don't normally need to call synchronize manually, as the system does periodically synch the userDefaults automatically, but if you need to push the changes immediately, then you need to force update via the synchronize call.

The documentation states this

Because this method is automatically invoked at periodic intervals, use this method only if you cannot wait for the automatic synchronization (for example, if your application is about to exit) or if you want to update the user defaults to what is on disk even though you have not made any changes.

Lefteris
  • 14,550
  • 2
  • 56
  • 95
  • 1
    Actually when I saw `synchronize()` in @Ryan Poolos answer I tried to use it and exactly like you , but still getting `10` when I print. Thanks – Zizoo Apr 13 '17 at 21:54
  • Which keys are present? Try printing them to see – Lefteris Apr 13 '17 at 21:57
  • AppleLanguages, AppleLocale, NSInterfaceStyle, AppleITunesStoreItemKinds, AppleKeyboardsExpanded, PKKeychainVersionKey, ApplePasscodeKeyboards , AppleKeyboards, NSLanguages, NSInterfaceStyle ... I really don't know what are these things – Zizoo Apr 13 '17 at 22:02
  • @Zizoo there is some keys that can't be cleared check this http://stackoverflow.com/a/27833340/2303865 – Leo Dabus Apr 13 '17 at 22:02
  • so when the count of keys is 10 , that means I have cleared all keys ? – Zizoo Apr 13 '17 at 22:03
  • Well if you don't see any off your keys, obviously – Lefteris Apr 13 '17 at 22:03
  • I have no idea how many but you just need to removePersistentDomain and thats it – Leo Dabus Apr 13 '17 at 22:04
  • 3
    You should update your answer to what actually answered the question rather than the suggestion to use synchronize. – dan Apr 13 '17 at 22:16
  • 4
    no need to force synchronize and no need to create a new array object to get the keys count `UserDefaults.standard.dictionaryRepresentation().keys.count` – Leo Dabus Apr 13 '17 at 22:16
80

This answer found here https://stackoverflow.com/a/6797133/563381 but just incase here it is in Swift.

func resetDefaults() {
    let defaults = UserDefaults.standard
    let dictionary = defaults.dictionaryRepresentation()
    dictionary.keys.forEach { key in
        defaults.removeObject(forKey: key)
    }
}
Ryan Poolos
  • 18,421
  • 4
  • 65
  • 98
  • Thank you, but I got `10` again :( – Zizoo Apr 13 '17 at 21:41
  • you never use `value`, so you should ignore it with `_` – Alexander Apr 13 '17 at 21:57
  • 4
    or better yet: `defaults.dictionaryRepresentation().keys.forEach(defaults.removeObject(forKey:)` – Alexander Apr 13 '17 at 21:58
  • 4
    from offical documentation about the syncrhonize() function: "this method is unnecessary and shouldn't be used" – Yetispapa Dec 08 '17 at 13:51
  • At the time this answer was written I think it was often necessary, but you're absolutely right at this point in time it is a deprecated function we no longer need on any modern iOS version. Updated the answer to cover that. – Ryan Poolos Dec 08 '17 at 13:55
  • 1
    Alexander's code was great. But it was missing a character. Should be: `defaults.dictionaryRepresentation().keys.forEach(defaults.removeObject(forKey:))` – Vette Jun 07 '19 at 22:52