@@ -19,7 +19,7 @@ extension NSPersistentStoreCoordinator
1919 :param: URL URL to save the SQLite store at, pass nil to use default
2020 :param: managedObjectModel Managed object model to initialize the store with, pass nil to use all models in the main bundle
2121 */
22- public convenience init ? ( automigrating: Bool , URL optionalURL: NSURL ? = nil , managedObjectModel optionalManagedObjectModel: NSManagedObjectModel ? = nil ) {
22+ public convenience init ? ( automigrating: Bool , deleteOnMismatch : Bool = false , URL optionalURL: NSURL ? = nil , managedObjectModel optionalManagedObjectModel: NSManagedObjectModel ? = nil ) {
2323
2424 // Fallback on the defaults
2525 let _managedObjectModel = optionalManagedObjectModel ?? NSManagedObjectModel . mergedModelFromBundles ( nil )
@@ -29,7 +29,7 @@ extension NSPersistentStoreCoordinator
2929 switch ( _managedObjectModel, _URL) {
3030 case let ( . Some( managedObjectModel) , . Some( URL) ) :
3131 self . init ( managedObjectModel: managedObjectModel)
32- self . addSQLitePersistentStoreWithURL ( URL, automigrating: automigrating)
32+ self . addSQLitePersistentStoreWithURL ( URL, automigrating: automigrating, deleteOnMismatch : deleteOnMismatch )
3333
3434 default :
3535 self . init ( )
@@ -70,30 +70,54 @@ extension NSPersistentStoreCoordinator
7070 :param: URL Location of the store
7171 :param: automigrating Whether the store should automigrate itself
7272 */
73- func addSQLitePersistentStoreWithURL( URL: NSURL , automigrating: Bool )
73+ private func addSQLitePersistentStoreWithURL( URL: NSURL , automigrating: Bool , deleteOnMismatch : Bool )
7474 {
75- let addStore : ( ) -> Void = {
75+ let addStore : ( ) -> Result < NSPersistentStore > = {
7676 let options = [
7777 NSMigratePersistentStoresAutomaticallyOption: automigrating,
7878 NSInferMappingModelAutomaticallyOption: automigrating,
7979 NSSQLitePragmasOption: [ " journal_mode " : " WAL " ]
8080 ] ;
8181
8282 var optionalError : NSError ?
83- self . addPersistentStoreWithType ( NSSQLiteStoreType, configuration: nil , URL: URL, options: options, error: & optionalError)
83+ let optionalStore = self . addPersistentStoreWithType ( NSSQLiteStoreType, configuration: nil , URL: URL, options: options, error: & optionalError)
8484
85- if let error = optionalError {
86- println ( " [CoreDataKit] Error while adding SQLite persistent store: \( error) " )
85+ switch ( optionalStore, optionalError) {
86+ case let ( . Some( store) , . None) :
87+ return Result ( store)
88+
89+ case let ( . None, . Some( error) ) :
90+ return Result ( error)
91+
92+ default :
93+ let error = NSError ( domain: CoreDataKitErrorDomain, code: CoreDataKitErrorCode . UnknownError. rawValue, userInfo: [ NSLocalizedDescriptionKey: " NSPersistentStoreCoordinator.addPersistentStoreWithType returned invalid combination of return value ( \( optionalStore) ) and error ( \( optionalError) ) " ] )
94+ return Result ( error)
8795 }
8896 }
8997
90- addStore ( )
98+ if let error = addStore ( ) . error ( ) {
99+ // Check for version mismatch
100+ if ( deleteOnMismatch && NSCocoaErrorDomain == error. domain && ( NSPersistentStoreIncompatibleVersionHashError == error. code || NSMigrationMissingSourceModelError == error. code) ) {
91101
92- // Workaround for "Migration failed after first pass" error
93- if ( automigrating && 0 == self . persistentStores. count)
94- {
95- println ( " [CoreDataKit] Applying workaround for 'Migration failed after first pass' bug, retrying... " )
96- dispatch_after ( dispatch_time ( DISPATCH_TIME_NOW, Int64 ( NSEC_PER_SEC) / 2 ) , dispatch_get_main_queue ( ) , addStore)
102+ println ( " [CoreDataKit] Model mismatch, removing persistent store... " )
103+ if let urlString = URL . absoluteString {
104+ let shmFile = urlString. stringByAppendingString ( " -shm " )
105+ let walFile = urlString. stringByAppendingString ( " -wal " )
106+ NSFileManager . defaultManager ( ) . removeItemAtURL ( URL, error: nil )
107+ NSFileManager . defaultManager ( ) . removeItemAtPath ( shmFile, error: nil )
108+ NSFileManager . defaultManager ( ) . removeItemAtPath ( walFile, error: nil )
109+ }
110+
111+ addStore ( )
112+ }
113+ // Workaround for "Migration failed after first pass" error
114+ else if automigrating {
115+ println ( " [CoreDataKit] Applying workaround for 'Migration failed after first pass' bug, retrying... " )
116+ dispatch_after ( dispatch_time ( DISPATCH_TIME_NOW, Int64 ( NSEC_PER_SEC) / 2 ) , dispatch_get_main_queue ( ) ) {
117+ addStore ( )
118+ return
119+ }
120+ }
97121 }
98122 }
99123}
0 commit comments