diff --git a/WordPress/Classes/Utility/ContextManager.swift b/WordPress/Classes/Utility/ContextManager.swift index dd6c899e8d68..4ade7fbf0555 100644 --- a/WordPress/Classes/Utility/ContextManager.swift +++ b/WordPress/Classes/Utility/ContextManager.swift @@ -135,6 +135,41 @@ public class ContextManager: NSObject, CoreDataStack, CoreDataStackSwift { save(context, .asynchronously) } } + + static func migrateDataModelsIfNecessary(storeURL: URL, objectModel: NSManagedObjectModel) throws { + guard FileManager.default.fileExists(atPath: storeURL.path) else { + DDLogInfo("No store exists at \(storeURL). Skipping migration.") + return + } + + guard let metadata = try? NSPersistentStoreCoordinator.metadataForPersistentStore(ofType: NSSQLiteStoreType, at: storeURL), + !objectModel.isConfiguration(withName: nil, compatibleWithStoreMetadata: metadata) + else { + return + } + + DDLogWarn("Migration required for persistent store.") + + guard let modelFileURL = Bundle.main.url(forResource: "WordPress", withExtension: "momd") else { + fatalError("Can't find WordPress.momd") + } + + guard let versionInfo = NSDictionary(contentsOf: modelFileURL.appendingPathComponent("VersionInfo.plist")) else { + fatalError("Can't get the object model's version info") + } + + guard let modelNames = (versionInfo["NSManagedObjectModel_VersionHashes"] as? [String: AnyObject])?.keys else { + fatalError("Can't parse the model versions") + } + + let sortedModelNames = modelNames.sorted { $0.compare($1, options: .numeric) == .orderedAscending } + try CoreDataIterativeMigrator.iterativeMigrate( + sourceStore: storeURL, + storeType: NSSQLiteStoreType, + to: objectModel, + using: sortedModelNames + ) + } } // MARK: - Private methods @@ -236,40 +271,6 @@ private extension ContextManager { return persistentContainer } - static func migrateDataModelsIfNecessary(storeURL: URL, objectModel: NSManagedObjectModel) throws { - guard FileManager.default.fileExists(atPath: storeURL.path) else { - DDLogInfo("No store exists at \(storeURL). Skipping migration.") - return - } - - guard let metadata = try? NSPersistentStoreCoordinator.metadataForPersistentStore(ofType: NSSQLiteStoreType, at: storeURL), - objectModel.isConfiguration(withName: nil, compatibleWithStoreMetadata: metadata) - else { - return - } - - DDLogWarn("Migration required for persistent store.") - - guard let modelFileURL = Bundle.main.url(forResource: "WordPress", withExtension: "momd") else { - fatalError("Can't find WordPress.momd") - } - - guard let versionInfo = NSDictionary(contentsOf: modelFileURL.appendingPathComponent("VersionInfo.plist")) else { - fatalError("Can't get the object model's version info") - } - - guard let modelNames = (versionInfo["NSManagedObjectModel_VersionHashes"] as? [String: AnyObject])?.keys else { - fatalError("Can't parse the model versions") - } - - let sortedModelNames = modelNames.sorted { $0.compare($1, options: .numeric) == .orderedAscending } - try CoreDataIterativeMigrator.iterativeMigrate( - sourceStore: storeURL, - storeType: NSSQLiteStoreType, - to: objectModel, - using: sortedModelNames - ) - } } extension ContextManager { diff --git a/WordPress/Classes/Utility/CoreDataHelper.swift b/WordPress/Classes/Utility/CoreDataHelper.swift index 9413094aa517..00b6bbe948ea 100644 --- a/WordPress/Classes/Utility/CoreDataHelper.swift +++ b/WordPress/Classes/Utility/CoreDataHelper.swift @@ -250,14 +250,19 @@ extension CoreDataStack { throw ContextManager.ContextManagerError.missingDatabase } + try? migrateDatabaseIfNecessary(at: databaseLocation) + mainContext.reset() try storeCoordinator.remove(store) let databaseReplaced = replaceDatabase(from: databaseLocation, to: currentDatabaseLocation) do { + let options = [NSMigratePersistentStoresAutomaticallyOption: true, + NSInferMappingModelAutomaticallyOption: true] try storeCoordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, - at: currentDatabaseLocation) + at: currentDatabaseLocation, + options: options) if databaseReplaced { // The database was replaced successfully and the store added with no errors so we @@ -327,4 +332,12 @@ extension CoreDataStack { _ = try? FileManager.default.replaceItemAt(locationShm, withItemAt: shmBackup) _ = try? FileManager.default.replaceItemAt(locationWal, withItemAt: walBackup) } + + private func migrateDatabaseIfNecessary(at databaseLocation: URL) throws { + guard let modelFileURL = Bundle.main.url(forResource: "WordPress", withExtension: "momd"), + let objectModel = NSManagedObjectModel(contentsOf: modelFileURL) else { + return + } + try ContextManager.migrateDataModelsIfNecessary(storeURL: databaseLocation, objectModel: objectModel) + } }