NSUserDefaults не видаляються після видалення програми на симуляторі


95

це може звучати по-справжньому NOOB! Я хочу перевірити, чи не входить користувач вдруге в мою програму, щоб зберегти кількість запуску, яку я використовую 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
Ви пробували тестування на реальному пристрої?
Генрі Ф

Вам потрібно видалити це вручну на тренажері. Ось як .
dasblinkenlight,

будь ласка, позначте правильну відповідь, щоб на це питання більше не залишалось відповідей
anders

1
@Reza: [[NSUserDefaults standardUserDefaults] setObject: selectedLists forKey: UserID]. Мій додаток аварійно завершує роботу тут, в iOS 8, хоча чудово працює в iOS 6 та iOS 7. Тут вибрані списки в NSMutable Array та UserId - це рядок.
Мантан

@Manthan, це дещо інша проблема, але я зіткнувся з тією ж проблемою десь ще, і причиною аварії було те, що Хоча об'єкт, який я NSMutableArrayзберігав для якогось ключа, був збережений як файл, NSArrayа його зміна призвела до аварійного завершення роботи мого додатка. .. Я рекомендую заощаджувати NSArrayі коли ви хочете використовувати його пізніше виливки його NSMutableArrayвикористання [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
Для тих, хто стикається з тим самим питанням. Якщо у вас більше однієї програми в одній групі, і всі вони використовують групи програм (увімкнено під можливостями), вам доведеться видалити всі програми з пристрою, щоб за замовчуванням користувач був видалений. Оскільки стандартні налаштування користувача є спільними, навіть якщо на пристрої є одна програма, вона не буде видалена, оскільки ця програма використовуватиме налаштування користувача.
Анкіт Шрівастава,

14

Оскільки скидання вмісту та налаштувань є ядерним варіантом, ви можете розглянути ще два варіанти, доки не буде вирішено помилку на симуляторі iOS 8 / Xcode 6 GM:

  1. Ви можете вручну видалити файл plist, де NSUserDefaultsвони зберігаються. На даний момент це знаходиться за адресою ~/Library/Developer/CoreSimulator/Devices/*some_device_id*/Library/Preferences/com.yourcompany.yourapp.plist Трохи нудно знаходити потрібний симулятор для роботи серед назв каталогів UUID. EDIT : 2014-10-28 20-34-52 Правильний шлях: ~/Library/Developer/CoreSimulator/Devices/*some_device_id*/data/Library/Preferences/com.yourcompany.yourapp.plist

  2. Ви можете виконати "операцію" на цьому plist (можливо, використовуючи фазу побудови сценарію запуску), використовуючи plistbuddy, наприклад

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


Ви відсутні / data / after / * some_device_id * /
Чувак

5

Для тих, хто стикається з тим самим питанням.

Якщо у вас більше однієї програми в одній групі, і всі вони використовують групи програм (Увімкнено під можливостями), вам доведеться видалити всі програми з пристрою, щоб за замовчуванням користувач був видалений.

Оскільки стандартні налаштування користувача є спільними, навіть якщо на пристрої є одна програма, вона не буде видалена, оскільки ця програма використовуватиме налаштування користувача.


4

Код повинен добре працювати на пристрої. Можливо, якісь помилки в симуляторі.

Спробуйте скинути зміст і налаштування симулятора.


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імітує перший запуск програми, коментуючи його, буде імітувати всі наступні запуски програми.


2

У моєму випадку я знайшов * .plist у наступному каталозі:

[1] / Users / SOME-USERNAME / Library / Developer / CoreSimulator / Devices / SOME -DEVICE-ID /data/Library/Preferences/SP.UserDefaultsTest.plist

Проблема: Видалення програми в xCode 6 (симулятор iOS 8), але файл залишається на диску, як зазначено вище.

Рішення: Видалення знайденого файлу із шляху [1] вручну, і NSUserDefaults зникнуть.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.