Очистка 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 -> Сбросить содержимое и настройки...

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

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

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

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

        self.removePersistentDomainForName(domainName)
    }
}

В Свифте:

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

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

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

Расширяя ответ Кристофер Роджерс - принятый.

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

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

[[NSUserDefaults standardUserDefaults] synchronize];

Я создал метод, чтобы сделать это,

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

Свифт?

С быстрым его еще проще.

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

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

UserDefaults.clean()

Я нашел это:

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

Это ошибка или что-то еще, кроме 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];
    }

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

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

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

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

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

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

[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
Другие вопросы по тегам