gpt4 book ai didi

ios - 后台获取间歇性数据丢失 - NSKeyedUnarchiver 可以从文档目录返回 nil 吗?

转载 作者:搜寻专家 更新时间:2023-11-01 06:10:52 24 4
gpt4 key购买 nike

我有一个简单的应用程序,它使用应用程序文档文件夹中的 NSCoding 存储自定义类型的数组(名为 Drug 的类的实例)。

加载和保存代码是对我的主视图 Controller 的扩展,一旦加载它就一直存在。

数组的初始化:

var drugs = [Drug]()

此数组随后会附加下面 loadDrugs() 方法的结果。

func saveDrugs() {
// Save to app container
let isSuccessfulSave = NSKeyedArchiver.archiveRootObject(drugs, toFile: Drug.ArchiveURL.path)

// Save to shared container (for iMessage, Spotlight, widget)
let isSuccessfulSaveToSharedContainer = NSKeyedArchiver.archiveRootObject(drugs, toFile: Drug.SharedArchiveURL.path)
}

这是加载数据的代码。

func loadDrugs() -> [Drug]? {
var appContainerDrugs = NSKeyedUnarchiver.unarchiveObject(withFile: Drug.ArchiveURL.path) as? [Drug]
return appContainerDrugs
}

数据也使用 CloudKit 存储在 iCloud 中,应用程序可以响应 CK 通知以从另一台设备获取更改。后台提取也会触发相同的方法。

// App Delegate
func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// Code to get reference to my main view controller
// This will have called loadDrugs() to populate local array drugs of type [Drug]
mainVC.getZoneChanges()
}

最后,还有 getZoneChanges() 方法,它使用存储的 CKServerChangeToken 通过 CKFetchRecordZoneChangesOperation 从私有(private)用户数据库获取更改.完成 block 调用 saveDrugs()

问题

所有这些似乎都运行良好。但是,有时所有本地数据都会在应用程序的使用之间消失,尤其是在一段时间未使用的情况下。谢天谢地,删除并重新安装该应用确实会从 iCloud 中提取备份数据。

如果应用有一段时间没有使用(可能被系统终止),似乎会发生这种情况。有些东西必须改变,所以我认为当应用程序终止时调用后台提取可能是问题所在。调试时以及应用最近处于前台时一切正常。

可能的原因

我猜问题是我依赖后台获取(或接收 CK 通知)在后台加载我的主视图 Controller ,然后加载保存的本地数据。

我听说 UserDefaults 在后台无法正常工作,在这种情况下可能存在文件安全保护以防止访问文档目录。如果是这种情况,我可能会加载一个空数组(或者更确切地说是初始化数组而不是将数据附加到它)然后保存它,覆盖现有数据,所有这些都在用户不知情的情况下进行。

如何避免这个问题?有没有办法检查数据是否正确加载?如果出现问题,我尝试使用 fatal error 进行条件加载,但这会导致应用程序首次运行时出现问题,因为无论如何都没有数据!


编辑

存档 URL 是动态获取的,如下所示。我只是在我的主数据模型类 (Drug) 中使用静态方法来访问它们:

static let DocumentsDirectory = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first!
static let ArchiveURL = DocumentsDirectory.appendingPathComponent("drugs")

最佳答案

此类问题的最常见原因是当设备被锁定且 protected 数据被加密时在后台被唤醒。

作为起点,您可以检查 UIApplication.isProtectedDataAvailable 以验证 protected 数据是否可用。您还可以将所需数据的保护级别降低到 .completeUntilFirstUserAuthentication(具体操作取决于您创建文件的方式)。

通常,您应该尽量减少敏感信息的数据保护级别,因此通常最好在设备锁定时写入其他位置,然后在设备解锁后合并该位置。

关于ios - 后台获取间歇性数据丢失 - NSKeyedUnarchiver 可以从文档目录返回 nil 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57758330/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com