88
99import CoreData
1010
11+ protocol CoreDataMigrating {
12+ func requiresMigration( at storeURL: URL ) -> Bool
13+ func migrateStore( at storeURL: URL )
14+ }
15+
1116/**
1217 Responsible for handling Core Data model migrations.
1318
@@ -24,16 +29,17 @@ import CoreData
2429 Then when we create model version 5, we only need to create one additional mapping 4 to 5. This greatly reduces the work
2530 required when adding a new version.
2631 */
27- class CoreDataMigrator {
32+ class CoreDataMigrator : CoreDataMigrating {
2833
2934 // MARK: - Check
3035
31- func requiresMigration( at storeURL: URL , currentMigrationModel : CoreDataMigrationModel = CoreDataMigrationModel . current ) -> Bool {
36+ func requiresMigration( at storeURL: URL ) -> Bool {
3237 guard let metadata = NSPersistentStoreCoordinator . metadata ( at: storeURL) else {
3338 return false
3439 }
3540
36- return !currentMigrationModel. managedObjectModel ( ) . isConfiguration ( withName: nil , compatibleWithStoreMetadata: metadata)
41+ return !CoreDataMigrationModel. current. managedObjectModel ( ) . isConfiguration ( withName: nil ,
42+ compatibleWithStoreMetadata: metadata)
3743 }
3844
3945 // MARK: - Migration
@@ -42,7 +48,9 @@ class CoreDataMigrator {
4248 migrateStore ( from: storeURL, to: storeURL, targetVersion: CoreDataMigrationModel . current)
4349 }
4450
45- func migrateStore( from sourceURL: URL , to targetURL: URL , targetVersion: CoreDataMigrationModel ) {
51+ private func migrateStore( from sourceURL: URL ,
52+ to targetURL: URL ,
53+ targetVersion: CoreDataMigrationModel ) {
4654 guard let metadata = NSPersistentStoreCoordinator . metadata ( at: sourceURL) ,
4755 let sourceMigrationModel = CoreDataMigrationModel . migrationModelCompatibleWithStoreMetadata ( metadata) else {
4856 fatalError ( " Unknown store version at URL \( sourceURL) " )
@@ -54,11 +62,20 @@ class CoreDataMigrator {
5462 let migrationSteps = sourceMigrationModel. migrationSteps ( to: targetVersion)
5563
5664 for step in migrationSteps {
57- let manager = NSMigrationManager ( sourceModel: step. source, destinationModel: step. destination)
58- let destinationURL = URL ( fileURLWithPath: NSTemporaryDirectory ( ) , isDirectory: true ) . appendingPathComponent ( UUID ( ) . uuidString)
65+ let manager = NSMigrationManager ( sourceModel: step. source,
66+ destinationModel: step. destination)
67+ let tmpDirectoryURL = URL ( fileURLWithPath: NSTemporaryDirectory ( ) ,
68+ isDirectory: true )
69+ let destinationURL = tmpDirectoryURL. appendingPathComponent ( UUID ( ) . uuidString)
5970
6071 do {
61- try manager. migrateStore ( from: currentURL, sourceType: NSSQLiteStoreType, options: nil , with: step. mapping, toDestinationURL: destinationURL, destinationType: NSSQLiteStoreType, destinationOptions: nil )
72+ try manager. migrateStore ( from: currentURL,
73+ sourceType: NSSQLiteStoreType,
74+ options: nil ,
75+ with: step. mapping,
76+ toDestinationURL: destinationURL,
77+ destinationType: NSSQLiteStoreType,
78+ destinationOptions: nil )
6279 } catch let error {
6380 fatalError ( " Failed attempting to migrate from \( step. source) to \( step. destination) , error: \( error) " )
6481 }
@@ -71,7 +88,8 @@ class CoreDataMigrator {
7188 currentURL = destinationURL
7289 }
7390
74- NSPersistentStoreCoordinator . replaceStore ( at: targetURL, withStoreAt: currentURL)
91+ NSPersistentStoreCoordinator . replaceStore ( at: targetURL,
92+ withStoreAt: currentURL)
7593
7694 if ( currentURL != sourceURL) {
7795 NSPersistentStoreCoordinator . destroyStore ( at: currentURL)
@@ -80,8 +98,9 @@ class CoreDataMigrator {
8098
8199 // MARK: - WAL
82100
83- func forceWALCheckpointingForStore( at storeURL: URL ) {
84- guard let metadata = NSPersistentStoreCoordinator . metadata ( at: storeURL) , let migrationModel = CoreDataMigrationModel . migrationModelCompatibleWithStoreMetadata ( metadata) else {
101+ private func forceWALCheckpointingForStore( at storeURL: URL ) {
102+ guard let metadata = NSPersistentStoreCoordinator . metadata ( at: storeURL) ,
103+ let migrationModel = CoreDataMigrationModel . migrationModelCompatibleWithStoreMetadata ( metadata) else {
85104 return
86105 }
87106
@@ -90,7 +109,8 @@ class CoreDataMigrator {
90109 let persistentStoreCoordinator = NSPersistentStoreCoordinator ( managedObjectModel: model)
91110
92111 let options = [ NSSQLitePragmasOption: [ " journal_mode " : " DELETE " ] ]
93- let store = persistentStoreCoordinator. addPersistentStore ( at: storeURL, options: options)
112+ let store = persistentStoreCoordinator. addPersistentStore ( at: storeURL,
113+ options: options)
94114 try persistentStoreCoordinator. remove ( store)
95115 } catch let error {
96116 fatalError ( " Failed to force WAL checkpointing, error: \( error) " )
0 commit comments