是这样吗?当您向 App Store 上的应用程序提交更新时,NSUserDefaults 会被重置,还是被重置?
我的应用程序在更新时崩溃,但在完全下载时不会崩溃 - 所以我试图确定更新后的会话与新下载的会话可能有什么不同。
干杯,尼克。
是这样吗?当您向 App Store 上的应用程序提交更新时,NSUserDefaults 会被重置,还是被重置?
我的应用程序在更新时崩溃,但在完全下载时不会崩溃 - 所以我试图确定更新后的会话与新下载的会话可能有什么不同。
干杯,尼克。
除非用户删除应用程序,否则它们通常不会重置。对于基本数据,NSUserDefaults 是保存首选项、日期、字符串等数据的最佳方式。如果您要保存图像和文件,文件系统是更好的选择。
我相信答案是肯定的,它将持续存在。这也完全记录在 Apple iPhone OS 编程指南的应用程序目录一章下。
如果您有 CoreData 模型并且您更改了模型和更新中的某些内容,而没有管理迁移,这可能是您的应用程序在更新时崩溃的原因......
我也有类似的经历。我们的应用程序在 Settings.Bundle/Root.Plist 中存储了一个版本号。这通过 iPhone 设置应用程序显示。我们发现,在安装时,版本号是从应用程序包中加载的——因此版本号是正确的。在更新时,版本号不会改变。这给人的印象是用户正在运行应用程序的早期版本。我们没有与版本号相关的任何逻辑,它只是为了显示(它可以供联络中心工作人员在诊断故障时使用)。
我们的经验是,当用户更新我们的应用程序时,NSUserDefaults 不会被清除,但设置显示也不会被更新。
请注意这种情况,当您的应用程序在后台运行并且您无法访问 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。在您的情况下,您不想从所有用户默认设置中删除保护,只是在首次解锁之前需要在后台访问的那些。
最后,如果这些数据中的任何一个是真正敏感的,您应该将其放入钥匙串中。值得注意的是,钥匙串确实具有逐项设置数据保护的能力。