设置 persistentStoreDescriptions 会导致不保存 CoreData 对象



我试图确保我们所有的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)

最新更新