ios CoreData ->基于某个值的多个数据存储

xxhby3vn  于 12个月前  发布在  iOS
关注(0)|答案(1)|浏览(105)

我有一个奇怪的需求,我怀疑答案将是“它不意味着这样工作”,但这里去(不,我还没有尝试过这个)-我需要能够击中各种数据存储在CoreData的基础上应用程序用户的登录。想象一下,一个电话被交给多个人,每个人都有自己的登录名。因此,如果Bob拥有手机并登录,它会创建/使用Bob独有的CoreData数据存储,然后当Bob注销并将手机交给桑迪时,她会登录并进行相同的交易。
我知道您在CoreData初始化代码中提供了CoreData数据存储的名称,但我读过许多文章,人们说如果该名称不是应用程序的名称,CoreData就会变得古怪。我不确定这是真的(还是真的?)),但我只是在这里吠错了树?
想法呢?

kqhtkvqz

kqhtkvqz1#

Core Data存储的名称不需要与应用的名称匹配。事实上,单个应用程序可以有多个名称不同的数据存储。
要实现这一点,您需要创建NSPersistentContainter,提供数据存储名称和托管对象模型。
也就是说,您需要NSPersistentContainer(name: storeName, managedObjectModel: managedObjectModel)而不是NSPersistentContainer(name: storeName)初始化程序。
最具挑战性的部分是获取当前版本数据模型的NSManagedObjectModel,但下面的代码片段将向您展示如何做到这一点:

Struct PersistenceController {

    let container: NSPersistentContainer
    
    init(userName: String,
         inMemory: Bool = false) {
        
        // Both the store and data model can be any string, for the sake of simplicity lets
        // consider your app's name
        let yourAppName = "YourAppName"
        
        // Append the userName to your data store name
        let storeName = "\(yourAppName)-\(userName)"
        
        // This must be the same name as the data model file in your project.
        // Typically is the same as the app's name
        let dataModelName = yourAppName
        
        // Here you get the managedObjectModel to create the persistent container
        guard let managedObjectModel = NSManagedObjectModel(name: dataModelName) else {
            fatalError("Cannot instantiate NSManagedObjectModel")
        }
        
        // When you create the persistent container specifying the name and the managed object model,
        // you "decouple" the name of the store from the name of the data model:
        container = NSPersistentContainer(name: storeName, managedObjectModel: managedObjectModel)
        
        
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        
        // Other code required for creating the persistent container goes here,
        // including the creation of the mainContex and any background context you need.
    }
}

extension NSManagedObjectModel {
    
    convenience init?(name: String) {
        
        let bundle = Bundle.main
        let dataModelFolder = "\(name).momd"  //Assuming your CoreData model is located in your project's roor directory
        
        // You need to read the current model version from the VersionInfo.plist file, located in the datamodel folder
        guard let versionPlistUrl = bundle.url(forResource: "VersionInfo",
                                               withExtension: "plist",
                                               subdirectory: dataModelFolder) else { fatalError("VersionInfo.plist doesn't exist") }
        
        // Here you parse the VersionInfo.plist file to a Dictionary and get the current version name:
        let versionPlist = NSDictionary(contentsOf: versionPlistUrl)
        let currentVersion = versionPlist?.object(forKey: "NSManagedObjectModel_CurrentVersionName") as? String
        
        // You need the current version model URL to instantiate the managed object model:
        guard let currentModelVersionURL = bundle.url(forResource: currentVersion,
                                                      withExtension: "mom",
                                                      subdirectory: dataModelFolder) else { fatalError("Model not found") }
        
        // Initialise the model with the url defined above
        self.init(contentsOf: currentModelVersionURL)
    }
}

相关问题