使用应用程序组处理框架中的coredata迁移?

时间:2018-05-18 19:37:21

标签: ios swift cocoa-touch core-data

我有一个Cocoa Touch Framework,其中包含了我的所有模型和其他与coredata堆栈相关的对象。堆栈将sqlite文件初始化为共享应用程序组中的位置。多个应用程序将共享这些模型并持久存储(因此需要将模型放在框架中并使用共享应用程序组来存储sqlite文件)。

这样可以正常工作,在2个应用之间共享数据,直到需要更新到框架导致迁移到coredata相关实体,因为我无法保证这两个应用都会在新版本的设备上更新该框架同时进行。这两个应用程序的代码仍然有效且运行良好(App A使用Framework V1,App B使用Framework V2),但sqlite数据库将从App B的更新迁移中修改。

是否可以使用coredata进行此操作?我可以使用FMDB或类似的方式使用sqlite(只要DB模式更新纯粹是附加的),但是想要coredata的便利。可以通过以下步骤说明coredata的问题:

  • App A安装了Framework V1&运行,coredata在应用程序组中创建数据库
  • App B安装了Framework V1&运行,不需要创建数据库,只需从应用程序组
  • 使用它
  • App B使用Framework V2&更新。运行,在DB上迁移以添加列/重命名列,一切都很好
  • App A再次运行(仍然使用Framework V1),撤消App B刚刚执行的操作(删除添加的列,从重命名的列中删除数据并重新命名)
  • 当两个应用程序来回运行时,数据库架构会不停地来回移动(由于迁移,我认为??)&数据丢失

我想用coredata做什么,或者我应该继续使用FMDB还是类似的?

使用FMDB,我可以手动控制数据库(创建/更改表)并转换到我的模型中,这样我就可以在转换为我的模型时添加/省略列,这样就可以使用相同的数据源。

下面的一些代码可以提供帮助(这可以假设所有应用程序都运行相同版本的框架):

let groupID = "group.com.company.sharedgroup"
let bundleID = "com.company.framework"
let modelName = "Model"

lazy var diskStoreDescription: NSPersistentStoreDescription = {
    let groupContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: groupID)!
    let sqliteURL = groupContainer.appendingPathComponent(modelName).appendingPathExtension("sqlite")
    return NSPersistentStoreDescription(url: sqliteURL)
}()

lazy var managedObjectModel: NSManagedObjectModel = {
    let bundle = Bundle(identifier: bundleID)!
    let momdURL = bundle.url(forResource: modelName, withExtension: "momd")!
    return NSManagedObjectModel(contentsOf: momdURL)!
}()

lazy var persistentContainer: NSPersistentContainer = {
    let container = NSPersistentContainer(name: modelName, managedObjectModel: managedObjectModel)
    container.persistentStoreDescriptions = [diskStoreDescription]
    container.loadPersistentStores {}
    return container
}()

核心数据具有魔力,并使表格ZOBJECT包含Z_PKZ_ENTZ_OPTZNAME

//Model V1
class Object: NSManagedObject {
    @NSManaged var name: String
}

核心数据具有魔力,并使用列ZOBJECT

更新表ZTITLE
//Model V2
class Object: NSManagedObject {
    @NSManaged var name: String
    @NSManaged var title: String?
}

在App B(使用Model V2)之后运行App A(使用Model V1)会删除ZTITLE列,但不会抛出异常或错误。然后重新运行App B(使用Model V2)重新创建ZTITLE。我希望App A继续正常运行,只需忽略ZTITLE。答案的范围可以从this is how you should do this...coredata is not meant to support this, use FMDB。谢谢!

0 个答案:

没有答案