我正在预加载一个sqlite数据库,然后将其与用于创建sqlite数据库的完全相同的数据模型捆绑到另一个项目中。 我的managedObjectContext的代码:
lazy var managedObjectContext: NSManagedObjectContext = {
guard let modelURL = Bundle.main.url(forResource: "DataModel", withExtension: "momd") else {
fatalError("Error getting data model url from the main bundle!")
}
guard let model = NSManagedObjectModel(contentsOf: modelURL) else {
fatalError("Error initiating the data model!")
}
let urls = FileManager.default.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask)
var documentsDirectory = urls[0]
let dataStoreURL = documentsDirectory.appendingPathComponent("DataStore.sqlite")
do {
try FileManager.default.copyItem(at: Bundle.main.url(forResource: "DataStore", withExtension: "sqlite")!, to: documentsDirectory.appendingPathComponent("DataStore.sqlite"))
try FileManager.default.copyItem(at: Bundle.main.url(forResource: "DataStore", withExtension: "sqlite-shm")!, to: documentsDirectory.appendingPathComponent("DataStore.sqlite-shm"))
try FileManager.default.copyItem(at: Bundle.main.url(forResource: "DataStore", withExtension: "sqlite-wal")!, to: documentsDirectory.appendingPathComponent("DataStore.sqlite-wal"))
} catch let error as NSError {
fatalError(error.debugDescription)
}
do{
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: model)
try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: dataStoreURL, options: nil)
let context = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
context.persistentStoreCoordinator = coordinator
return context
} catch let error as NSError {
fatalError("Error adding persistent store at \(dataStoreURL): \(error)")
}
}()
当我运行项目时,我收到此错误:
reason=The model used to open the store is incompatible with the one used to create the store
我使用完全相同的数据模型;怎么会不相容?
有人可以帮我理解我做错了吗?
更新:我发现问题,我试图将预装的sqlite数据库复制到文档目录中,即使首先存在一个。我添加了一个条件,如果数据库不存在,只能将数据库从主包复制到第一次运行的文档目录。更新后的代码如下:
lazy var managedObjectContext: NSManagedObjectContext = {
//**********************Getting Data Model********************************
guard let dataModelURL = Bundle.main.url(forResource: "DataModel", withExtension: "mom") else {
fatalError("Failed to get data model URL from main bundle!")
}
guard let dataModel = NSManagedObjectModel(contentsOf: dataModelURL) else {
fatalError("Failed to initiate data model from the main bundle!")
}
//**********************Getting persistence store*************************
let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let dataStoreURL = documentsDirectoryURL.appendingPathComponent("DataStore.sqlite")
if !FileManager.default.fileExists(atPath: dataStoreURL.path){
let sourceSqliteURLs = [Bundle.main.url(forResource: "DataStore", withExtension: "sqlite"), Bundle.main.url(forResource: "DataStore", withExtension: "sqlite-shm"), Bundle.main.url(forResource: "DataStore", withExtension: "sqlite-wal")]
let destSqliteURLs = [documentsDirectoryURL.appendingPathComponent("DataStore.sqlite"), documentsDirectoryURL.appendingPathComponent("DataStore.sqlite-shm"), documentsDirectoryURL.appendingPathComponent("DataStore.sqlite-wal")]
for (index, sourceURL) in sourceSqliteURLs.enumerated() {
do{ try FileManager.default.copyItem(at: sourceURL!, to: destSqliteURLs[index])
}catch{
fatalError("Error while copying data store files from main bundle to the documents directory!")
}
}
}
do{
let persistenceCordinator = NSPersistentStoreCoordinator(managedObjectModel: dataModel)
try persistenceCordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: dataStoreURL, options: nil)
//*******************Initiating managed object context******************
let context = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
context.persistentStoreCoordinator = persistenceCordinator
return context
}catch let error as NSError{
print(error.debugDescription)
fatalError("Error initiating managed object context!")
}
}()