Я выполняю резервное копирование и восстановление (через Dropbox) пользовательских Core Data
постоянных данных.Для восстановления я извлекаю файлы из Dropbox и временно сохраняю их в каталоге Documents.Затем я создаю новый NSPersistentContainer
и использую его для замены текущего постоянного хранилища (в каталоге ApplicationSupport) перед удалением ненужных файлов в каталоге Documents.
Сейчас я использую шаблон MasterDetailи поэтому у меня есть обычные сущности с метками времени и NSFetchedResultsController
, которые идут вместе с этим.После замены я возвращаюсь к основному tableView и, к сожалению, вижу исходный набор сущностей.Когда приложение перезагружается, я вижу восстановленные данные, как и предполагалось, но необходимо выяснить, как заставить NSFetchedResultsController
автоматически видеть новые восстановленные данные.
Это мой код восстановления:
func restorePSFromBackup() {
// Current persistent store is in the ApplicationSupport directory.
let currentPSFolderUrl = FileManager.default.urls(for: .applicationSupportDirectory, in:.userDomainMask).first!
// The current Core Data file (url).
let currentPSUrl1 = currentPSFolderUrl.appendingPathComponent("DBCDTest.sqlite")
// Backup persistent store with which to restore is in the Documents directory.
let backUpFolderUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
// The 3 backup Core Data files (urls).
let backupUrl1 = backUpFolderUrl.appendingPathComponent("DBCDTest.sqlite")
let backupUrl2 = backUpFolderUrl.appendingPathComponent("DBCDTest.sqlite-wal")
let backupUrl3 = backUpFolderUrl.appendingPathComponent("DBCDTest.sqlite-shm")
let sourceSqliteURLs = [backupUrl1, backupUrl2, backupUrl3]
let container = NSPersistentContainer(name: "DBCDTest")
do {
// Replace current persistent store with the restore/backup persistent store.
try container.persistentStoreCoordinator.replacePersistentStore(at: currentPSUrl1, destinationOptions: nil, withPersistentStoreFrom: backupUrl1, sourceOptions: nil, ofType: NSSQLiteStoreType)
// Delete the restore/backup files from the Application directory.
do {
for index in 0..<sourceSqliteURLs.count {
try FileManager.default.removeItem(at: sourceSqliteURLs[index])
}
} catch let error {
print("Failed to delete sqlite files.")
print(error.localizedDescription)
}
} catch let error {
print("Failed to replace persistent store.")
print(error.localizedDescription)
}
}
Вместо создания нового NSPersistentContainer
я попытался использовать инъекцию зависимостей для ссылки на созданную в AppDelegate и использовать ее для выполнения подкачки, но при попытке заменить постоянные хранилища не удается.Может ли это быть какая-то проблема NSManagedObjectContext
?Может ли потребоваться очистка перед доступом к новому хранилищу данных?