Недавно в своем приложении я обновил старые записанные данные ядра obj c новыми. Чтобы помочь с миграцией, я создал пользовательский PersistenceContainer
, который имеет такой код миграции:
override init(name: String, managedObjectModel model: NSManagedObjectModel) {
super.init(name: name, managedObjectModel: model)
performMigration(from: oldStoreURL:, to: newStoreURL)
}
private func performMigration(from oldPersistentStoreURL: URL, to newPersistentStoreURL: URL) {
guard FileManager.default.fileExists(atPath: oldPersistentStoreURL.path) else {
// No file at the old url, so we can create new store
return
}
let storeOptions = [NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true]
do {
let oldStore = try persistentStoreCoordinator.addPersistentStore(ofType: NSSQLiteStoreType,
configurationName: nil,
at: oldPersistentStoreURL,
options: storeOptions)
do {
try persistentStoreCoordinator.migratePersistentStore(oldStore,
to: newPersistentStoreURL,
options: storeOptions,
withType: NSSQLiteStoreType)
try FileManager.default.removeItem(at: oldPersistentStoreURL)
} catch let error {
print("Migration Error: ", error)
}
} catch {
print("Adding existing store error: ", error)
}
}
При тестировании на симуляторе или реальном устройстве миграция с предыдущей версии работает нормально, и данные передаются правильно, и я могу использовать приложение, как я делал раньше. Однако после выпуска у пользователя возникают проблемы при вызове метода migratePersistentStore:toURL:options:withType:
. Примеры ошибок:
Error Domain=NSCocoaErrorDomain Code=133000 "Attempt to access an object not found in store." UserInfo={NSUnderlyingException=Referential integrity problem found during migratePersistentStore:toURL:options:withType:error: CoreData
could not fulfill a fault for <ObjectID>
Error Domain=NSCocoaErrorDomain Code=133021 "(null)" UserInfo={NSExceptionOmitCallstacks=true, conflictList=("NSConstraintConflict...
Referential integrity problem found during...
Не знаю, помогает ли эта информация, но ранее старый стек Базовых данных создавал контексты main
и background
, а также добавлял постоянное хранилище вручную по URL и вручную определял местоположение NSManagedObjectModel
. Как я понял, новые Core Data теперь могут выполнять всю эту работу автоматически. В результате единственный оставшийся код из предыдущего стека -
let mainContext = persistentContainer.viewContext
mainContext.mergePolicy = NSMergePolicy.mergeByPropertyStoreTrump
mainContext.automaticallyMergesChangesFromParent = true
let backgroundContext = persistentContainer.viewContext
backgroundContext.mergePolicy = NSMergePolicy.mergeByPropertyStoreTrump
backgroundContext.automaticallyMergesChangesFromParent = true
Итак, мой вопрос: как исправить эту ошибку правильно и есть ли способ ее воспроизвести? Также в случае ошибки, подобной этой, означает ли это, что она вызвана миграцией или проблема возникла в старом магазине?
Буду признателен за любую помощь, заранее спасибо!