Skip to content
This repository was archived by the owner on Feb 8, 2023. It is now read-only.

Commit 3931f94

Browse files
committed
Add option to remove store on version mismatch
1 parent 6e0057f commit 3931f94

File tree

1 file changed

+37
-13
lines changed

1 file changed

+37
-13
lines changed

CoreDataKit/NSPersistentStoreCoordinator.swift

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)