NSUserDefaults не очищается после удаления приложения на симуляторе

95

это может показаться настоящим НООБ! Я хочу проверить, входит ли пользователь в мое приложение во второй раз, чтобы сохранить счетчик запусков, который я использую NSUserDefaults. Я осуществил следующий код в моем rootViewController«сек viewDidLoadметода:

    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

    NSLog(@"hello %ld", (long)[userDefaults integerForKey:@"runCount"]);

    if ([userDefaults integerForKey:@"runCount"] != 1) {
        //not the 2nd run
        [userDefaults setInteger:1 forKey:@"runCount"];
        NSLog(@"not 2nd run");
    } else {
        //second run or more
        NSLog(@"2nd run");
    }

    [userDefaults synchronize];

все работает нормально, но проблема в том, что когда я удаляю (удаляю и переустанавливаю) приложение согласно здесь и здесь, данные должны быть очищены, но это не так, и после переустановки приложения предыдущие данные все еще отображаются. Я запускаю свое приложение на симуляторе iOS с использованием xCode6-beta и нацелен на приложение на iOS 8

Реза Шайестехпур
источник
2
Вы пробовали тестировать на реальном устройстве?
Henry F
Вам нужно вручную очистить его на симуляторе. Вот как .
dasblinkenlight
отметьте, пожалуйста, правильный ответ, чтобы этот вопрос больше не оставался без ответа
anders
1
@Reza: [[NSUserDefaults standardUserDefaults] setObject: selectedLists forKey: UserID]. Мое приложение вылетает здесь в ios8, хотя отлично работает в ios6 и ios7. Здесь selectedlists в NSMutable Array, а UserId - это строка.
Manthan
@Manthan, это какая-то другая проблема, но я столкнулся с той же проблемой где-то в другом месте, и причина, вызвавшая сбой, заключалась в том, что объект, который я NSMutableArrayсохранял для некоторого ключа, был сохранен как a, NSArrayи изменение его привело к сбою моего приложения. .. Я рекомендую сохранить a NSArrayи, когда вы захотите использовать его позже, преобразовать его в NSMutableArrayusing [NSMutableArray arrayWithArray:array];. Надеюсь, это поможет.
Реза Шайестехпур

Ответы:

169

Я думаю, это связано с ошибкой в ​​симуляторе iOS8 Beta Simulator.

Ожидаемое поведение заключается в том, что при удалении приложения также удаляются NSUserDefaults для этого приложения.

  • Однако NSUserDefaults НЕ удаляются при удалении приложения из симулятора.
  • Они правильно удаляются, когда вы удаляете их с физического устройства под управлением iOS8.

Быстрое и неприятное решение на данный момент - нажать iOS Simulator -> Reset Content and Settings.

Xcode 9.2 с Simulator 10 по-прежнему представляет эту проблему. Параметр меню теперь «Оборудование». Удалить все содержимое и настройки

Я отправил отчет об ошибке, кстати

Андерс
источник
45
Протестировал его на iOS 8 GM, и ошибка все еще существует. Очень надоедливый.
Манфред Шайнер
1
Я также могу подтвердить это ошибочное поведение в симуляторе Xcode 6 GM и iOS 8 (12A365)!
Борис Брдарич
1
Существующая ссылка на Open Radar для тех, кто хочет следить за этим делом: openradar.appspot.com/18540702
viggio24
1
Похоже, что ошибка исправлена ​​в SDK 8.1 после обновления до XCode 6.1 (6A1052d)
kas-kad
2
Для тех, кто сталкивается с той же проблемой. Если у вас есть более 1 приложения в одной группе, и все они используют группы приложений (ВКЛЮЧЕНО в разделе «Возможности»), вам придется удалить все приложения с устройства, чтобы очистить настройки пользователя по умолчанию. Поскольку пользовательские настройки по умолчанию являются общими, даже если одно из приложений находится на устройстве, оно не будет удалено, так как это приложение будет использовать пользовательские настройки.
Анкит Шривастава
14

Поскольку сброс содержимого и настроек является ядерным вариантом, вы можете рассмотреть два других варианта, пока не будет устранена ошибка в симуляторе iOS 8 / Xcode 6 GM:

  1. Вы можете вручную удалить файл plist, в котором NSUserDefaultsхранятся файлы. В настоящее время он находится по адресу ~/Library/Developer/CoreSimulator/Devices/*some_device_id*/Library/Preferences/com.yourcompany.yourapp.plist . Немного утомительно найти подходящий симулятор для работы среди имен каталогов UUID. РЕДАКТИРОВАТЬ : 2014-10-28 20-34-52 Правильный путь: ~/Library/Developer/CoreSimulator/Devices/*some_device_id*/data/Library/Preferences/com.yourcompany.yourapp.plist

  2. Вы можете выполнить «операцию» над этим списком (возможно, используя этап сборки сценария выполнения), используя plistbuddy, например

/usr/libexec/plistbuddy -c "Set :BSDidMoveSqliteDb 0" path_to_plist

Пушистый шимпанзе
источник
Вам не хватает / data / after / * some_device_id * /
чувак
5

Для тех, кто сталкивается с той же проблемой.

Если у вас есть более 1 приложения в одной группе, и все они используют группы приложений (ВКЛЮЧЕНО в разделе «Возможности»), вам придется удалить все приложения с устройства, чтобы очистить настройки пользователя по умолчанию.

Поскольку пользовательские значения по умолчанию являются общими, даже если одно из приложений находится на устройстве, оно не будет удалено, поскольку это приложение будет использовать пользовательские настройки.

Анкит Шривастава
источник
4

Код должен нормально работать на устройстве. Возможно какие-то баги в симуляторе.

Попробуйте сбросить содержимое и настройки симулятора.

ppalancica
источник
1
Сброс содержимого и настроек работает нормально, и в данный момент у меня нет устройства, чтобы проверить. tnx :)
Reza Shayestehpour
4

это ошибка, и вы можете удалить NSUserDefaults с помощью следующего кода

 NSString *appDomain = [[NSBundle mainBundle] bundleIdentifier];
 [[NSUserDefaults standardUserDefaults] removePersistentDomainForName:appDomain];
Игверик
источник
2

Хотя это все еще ошибка, другой вариант может заключаться в удалении определенного ключа (ключей) в NSUserDefaults. В большинстве случаев при тестировании / разработке мы заботимся только о нескольких ключах, а не обо всем в NSUserDefaults. Если вас интересуют только несколько ключей, я предлагаю добавить removeObjectForKey:

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
// ADD THIS TO SIMULATE CLEAN/EMPTY DEFAULTS, COMMENT OUT AFTER INITIAL EXECUTION.
// This will cause the TRUE case to be executed.
[userDefaults removeObjectForKey:@"runCount"]

NSLog(@"hello %ld", (long)[userDefaults integerForKey:@"runCount"]);

if ([userDefaults integerForKey:@"runCount"] != 1) {
    //not the 2nd run
    [userDefaults setInteger:1 forKey:@"runCount"];
    NSLog(@"not 2nd run");
} else {
    //second run or more
    NSLog(@"2nd run");
}

[userDefaults synchronize];

Добавление removeObjectForKeyимитирует первый запуск приложения, а его комментирование будет моделировать все последующие выполнения приложения.

AdamT
источник
2

В моем случае я нашел * .plist в следующем каталоге:

[1] / Users / НЕКОТОРЫЕ- ИМЯ-ПОЛЬЗОВАТЕЛЯ / Библиотека / Разработчик / CoreSimulator / Devices / НЕКОТОРЫЕ-УСТРОЙСТВО-ID /data/Library/Preferences/SP.UserDefaultsTest.plist

Проблема: удаление приложения в xCode 6 (симулятор iOS 8), но файл остается на диске, как указано выше.

Решение. Удалив найденный файл по пути [1] вручную, NSUserDefaults исчезнут.

Так что раздражающий способ сбросить симулятор больше не нужен.

sys4tron
источник