我试图确保我们所有的CoreData都受到数据保护的保护。 当我尝试在我的容器上设置 NSPersistentStoreDescription 时,没有保存任何 CoreData 对象。 如果我注释掉下面指示的行,所有对象都可以保存(和读取(即可。 如果我启用该行,则不会保存任何内容(或者读取可能静默失败? 不会生成错误,也不会生成日志。 我的配置文件中确实有数据保护权利(匹配完全除非打开(。 我一定错过了一些非常基本的东西。
这是 Xcode 8.2.1 (8C1002(
任何人都可以提供任何见解/建议吗?
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "my_app")
let description = NSPersistentStoreDescription()
description.shouldInferMappingModelAutomatically = true
description.shouldMigrateStoreAutomatically = true
description.setOption(FileProtectionType.completeUnlessOpen as NSObject?, forKey: NSPersistentStoreFileProtectionKey)
// *** ALLOWING THIS NEXT LINE TO EXECUTE CAUSES PROBLEM ***
container.persistentStoreDescriptions = [description]
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
print("Unresolved error (error), (error.userInfo)")
fatalError("Unresolved error (error), (error.userInfo)")
}
})
return container
}()
这个问题很久以前就被问过了,但我仍然会发布一个答案,以便任何遇到这个问题的人都能得到一些帮助。
在问题中发布的上述代码片段中,您没有使用 SQLITE 文件 URL 初始化 NSPersistentStoreDescription。
因此,它不知道它代表什么持久容器。请参考下面的工作代码。
let container = NSPersistentContainer(name: "AppName")
if let storeDirectory = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first {
let sqliteURL = storeDirectory.appendingPathComponent("AppName.sqlite")
//Set Protection for Core data sql file
let description = NSPersistentStoreDescription(url: sqliteURL)
description.shouldInferMappingModelAutomatically = true
description.shouldMigrateStoreAutomatically = true
description.setOption(FileProtectionType.complete as NSObject, forKey: NSPersistentStoreFileProtectionKey)
container.persistentStoreDescriptions = [description]
}
container.loadPersistentStores(completionHandler: { (storeDescription, error) in...}
让我知道这是否适合您,如果适合,请接受答案,以便其他人知道。
您的错误实际上是因为您正在设置与核心数据相关的选项。文件保护在FileManager
setAttributes
函数调用下完成。
但是,根本问题的答案是,您不需要向单个文件添加文件保护 - 它们设置为您在授权中声明的默认保护。
这可以通过打印以下输出来验证:
let attributes = try FileManager.default.attributesOfItem(atPath: url.relativePath)