Сохраняются ли NSUserDefaults через обновление приложения в Appstore?

106

Так ли это? Сбрасываются ли NSUserDefaults при отправке обновления приложения в App Store, или они сбрасываются?

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

Привет, Ник.

Ник Картрайт
источник
Файлы в Документах и Библиотеке будут сохранены в соответствии с утверждениями документации: developer.apple.com/library/ios/#DOCUMENTATION/iPhone/…
Джери Борбас

Ответы:

116

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

Coneybeare
источник
5
Упоминается ли где-нибудь в документации Apple?
Ник Картрайт,
1
Извините - я забыл поблагодарить вас за быстрый ответ! - Если бы кто-нибудь мог найти ссылку на любую форму документации Apple, в которой говорится об этом, было бы отлично .... В документации для NSUserDefaults ничего не говорится об этом, поэтому я думаю, что (ошибочно) предполагал, что значения по умолчанию будут удалены. Это, безусловно, кажется самым безопасным способом для Apple обновлять приложения!
Ник Картрайт,
Это может быть самый безопасный способ, но было бы невероятно раздражающим для пользователей, если бы им приходилось заново устанавливать все свои настройки при каждом обновлении приложения. Обычно у меня три или четыре обновления приложений в день; Я уверен, что у других пользователей iPhone их даже больше. Очистка настроек для каждого обновления в основном сделает мой iPhone непригодным для использования.
Кристофер Джонсон,
1
Данные в папке документов могут исчезнуть так же легко, как и NSUserDefaults. Однако они оба являются редкими случаями и не имеют абсолютно ничего общего с обычным процессом обновления
coneybeare
1
Спасибо, Кристофер - и да, я согласен. Моя проблема заключалась в том, что я использовал NSUserDefaults для хранения программных событий и полагался на их сброс при установке приложения. Все мои тесты на устройстве iPhone (и тестирование Apple) тестировали приложение как новую установку. Без какой-либо документации или способа тестирования в качестве обновления я не смог повторить сбой обновления, с которым сейчас сталкиваются все наши клиенты. Подводя итог - наверное, урок усвоен на горьком опыте !!
Ник Картрайт,
7

Я верю, что ответ ДА, так и будет. Это также полностью задокументировано в главе «Каталог приложений» в Руководстве по программированию Apple iPhone OS.

Леон
источник
4
  1. Прямой ответ на заданный вопрос: ДА.
  2. Ваша проблема: ваше приложение вылетает из-за проблем с логикой. Предположим, вы сохраняете объект по умолчанию, и приложение проверяет его значение при запуске (или в другом месте). При обновлении вы можете изменить способ его проверки или использования, например, вы ожидаете значение, но объект равен нулю, или наоборот. Это может вызвать SIGABRT или EXC_BAD_ACCESS.
Джон Смит
источник
2

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

Боян Божович
источник
Я ожидал, что это может быть случай :) не NSUserdefault
Джулиан
1

У меня есть подобный опыт. Наше приложение хранит номер версии в Settings.Bundle / Root.Plist. Это отображается в приложении настроек iPhone. Мы обнаружили, что при установке номер версии загружается из пакета приложения, поэтому номер версии правильный. Однако при обновлении номер версии не меняется. Создается впечатление, что пользователь использует предыдущую версию приложения. У нас нет никакой логики, связанной с номером версии, это просто для отображения (может использоваться сотрудниками контакт-центра при диагностике неисправностей).

Наш опыт показывает, что NSUserDefaults не очищается, когда пользователь обновляет наше приложение, но и отображение настроек не обновляется.

Дерек Найт
источник
0

Помните об этом случае, когда ваше приложение работает в фоновом режиме и вы не можете получить доступ к своим сохраненным значениям в NSUserDefaults:

Эрик:

По этому поводу было много потоков и ошибок, но это снова происходит со мной в ios 9. У меня есть приложение, которое запускается в фоновом режиме в ответ на задачи NSURLSession и толчки с доступным содержимым. Воспроизводимо, если я перезагружаю свой телефон и жду фонового запуска моего приложения, тогда, когда я открываю приложение, я обнаруживаю, что [[NSUserDefaults standardUserDefaults] dictionaryRepresentation] содержит все системные значения, например AppleITunesStoreItemKinds и т. Д., Но не содержит любое из установленных мной значений. Если я выйду принудительно и перезапущу приложение, все мои значения вернутся. Есть ли способ избежать кэширования «пустых» значений standardUserDefaults до разблокировки телефона или, по крайней мере, определить, когда они испорчены, и исправить их без принудительного выхода из приложения?

Эскимосский (eskimo1@apple.com):

Проблема здесь в том, что NSUserDefaults в конечном итоге поддерживается файлом в контейнере вашего приложения, а контейнер вашего приложения подлежит защите данных. Если вы ничего особенного не сделаете, то в iOS 7 и новее ваш контейнер использует NSFileProtectionCompleteUntilFirstUserAuthentication, значение, которое наследуется резервным хранилищем NSUserDefaults, и поэтому вы не можете получить к нему доступ до первой разблокировки.

IMO лучший способ обойти это - избегать NSUserDefaults для вещей, на которые вы полагаетесь в путях кода, которые могут выполняться в фоновом режиме. Вместо этого сохраните эти настройки в своем собственном файле настроек, в котором вы можете явно управлять защитой данных (в данном случае это означает «установить NSFileProtectionNone»).

Есть две проблемы с NSUserDefaults в контексте защиты данных:

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

Примечание. В последних версиях OS X NSUserDefaults управляется демоном, и люди, которые пытаются напрямую управлять его резервным хранилищем, сталкиваются с проблемами. Легко представить, что в какой-то момент подобное произойдет и с iOS.

Даже если бы изменение защиты данных было возможно, NSUserDefaults не имеет механизма для классификации данных на основе контекста, в котором вы их используете; это API "все или ничего". В вашем случае вы не хотите снимать защиту со всех своих пользовательских настроек по умолчанию, а только с тех, к которым вам нужно получить доступ в фоновом режиме перед первой разблокировкой.

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

Источник: https://webcache.googleusercontent.com/search?q=cache:sR9eZNHpZtwJ:https://forums.developer.apple.com/thread/15685.

Гранд М
источник