Очистка NSUserDefaults

Я использую +[NSUserDefaults standardUserDefaults] для хранения настроек приложения. Он состоит примерно из дюжины строковых значений. Можно ли удалить эти значения навсегда, а не просто установить их значение по умолчанию?

15 ответов


вы можете удалить постоянный домен приложения следующим образом:

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

в Swift 3 и позже:

if let bundleID = Bundle.main.bundleIdentifier {
    UserDefaults.standard.removePersistentDomain(forName: bundleID)
}

Это похоже на ответ @samvermette, но немного чище IMO.


этот код сбрасывает значения по умолчанию для домена регистрации:

[[NSUserDefaults standardUserDefaults] setPersistentDomain:[NSDictionary dictionary] forName:[[NSBundle mainBundle] bundleIdentifier]];

иными словами,removeObjectForKey для каждого ключа, который вы когда-либо зарегистрированных в этом приложении.

кредиты Кену Томасу на этом форуме разработчиков Apple нить.


вы пытались использовать -removeObjectForKey?

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

вот ответ в Swift:

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

Если вам это нужно во время разработки, вы также можете сбросить ваш симулятор, удалив все NSUserDefaults.

iOS Simulator - > сброс содержимого и настроек...

имейте в виду, что он также удалит все приложения и файлы на симуляторе.


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

В Swift:

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

Я нашел вот это:

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 "{}"

источник:https://gist.github.com/ZevEisenberg/5a172662cb576872d1ab


Я люблю расширения, когда они делают код чище:

extension NSUserDefaults {
    func clear() {
        guard let domainName = NSBundle.mainBundle().bundleIdentifier else {
            return
        }

        self.removePersistentDomainForName(domainName)
    }
}

Примечание: этот ответ был обновлен для Swift тоже.

как насчет того, чтобы иметь его на одной линии?

расширение @Christopher Rogers ответ-принятый.

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

и да, когда-нибудь вам может понадобиться synchronize он,

[[NSUserDefaults standardUserDefaults] synchronize];

Я создал метод для этого,

- (void) clearDefaults {
    [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

Свифт?

С swift его еще проще.

extension UserDefaults {
    class func clean() {
        guard let aValidIdentifier = Bundle.main.bundleIdentifier else { return false }
        self.standard.removePersistentDomain(forName: aValidIdentifier)
        self.standard.synchronize()
    }
}

и использование:

UserDefaults.clean()

это ошибка или что-то еще, но removePersistentDomainForName не работает при очистке все NSUserDefaults значения.

Итак, лучший вариант-это сбросить PersistentDomain и это вы можете сделать следующим образом:

NSUserDefaults.standardUserDefaults().setPersistentDomain(["":""], forName: NSBundle.mainBundle().bundleIdentifier!)

расширение ответа @folse... Я считаю, что более правильной была бы реализация...

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];
    }

...вызов метода persistentDomainForName: NSUserDefault. Как указано в документе, метод " возвращает словарь, содержащий ключи и значения в указанном постоянном домене."Вызов dictionaryRepresentation: вместо этого вернет словарь, который, вероятно, будет включать другие настройки, поскольку он применяется к более широкой области.

Если вам нужно, чтобы отфильтровать любые значения, которые должны быть сброшены, а затем итерация по ключам-это способ сделать это. Очевидно, что если вы хотите просто уничтожить все префы для приложения без учета, то один из других методов, опубликованных выше, является наиболее эффективным.


все вышеперечисленные ответы очень актуальны, но если кто-то все еще не может сбросить userdefaults для удаленного приложения, то вы можете сбросить настройки содержимого симулятора, и он будет работать.enter image description here


если параметр приложения, требующий сброса, является nsuserdefault для доступа к микрофону( мой случай), простым решением является ответ от Энтони Маккормика ( Iphone - Как включить доступ приложений к медиа на устройстве? - Код ALAssetsLibraryErrorDomain=-3312 "глобальный отказ в доступе").

на устройстве перейдите в Настройки>Общие>Сброс>Сброс предупреждений о местоположении


попробуйте это, это работает для меня .

одна строка кода

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