Skip to content

Instantly share code, notes, and snippets.

@pyrabbit
Created March 22, 2017 15:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pyrabbit/0b2411abad991bab1c7abfd581178ef4 to your computer and use it in GitHub Desktop.
Save pyrabbit/0b2411abad991bab1c7abfd581178ef4 to your computer and use it in GitHub Desktop.
Core Data migration problem
// New Core Data Stack for iOS 9+ inspired by https://useyourloaf.com/blog/easier-core-data-setup-with-persistent-containers/
lazy var applicationDocumentsDirectory: URL = {
// The directory the application uses to store the Core Data store file. This code uses a directory named "com.cadiridris.coreDataTemplate" in the application's documents Application Support directory.
let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return urls[urls.count-1]
}()
lazy var managedObjectModel: NSManagedObjectModel = {
// The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model.
let modelURL = Bundle.main.url(forResource: "MyApp", withExtension: "momd")!
return NSManagedObjectModel(contentsOf: modelURL)!
}()
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
// The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let supportDirectory = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first!
let url = supportDirectory.appendingPathComponent("MyApp.sqlite")
var failureReason = "There was an error creating or loading the application's saved data."
if !(FileManager.default.fileExists(atPath: supportDirectory.path)) {
print("[Debug] Could not find \(supportDirectory). Will create now.")
do {
try FileManager.default.createDirectory(at: supportDirectory, withIntermediateDirectories: true, attributes: nil)
} catch {
let nserror = error as NSError
Rollbar.error(withMessage: "Could not create the necessary ApplicationSupport directory for the SQLite database. \(error)")
}
}
do {
try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: nil)
} catch {
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" as AnyObject?
dict[NSLocalizedFailureReasonErrorKey] = failureReason as AnyObject?
dict[NSUnderlyingErrorKey] = error as NSError
let wrappedError = NSError(domain: "com.example.MyApp", code: 9999, userInfo: dict)
Rollbar.error(withMessage: "Unresolved persistantStoreCoordinator error \(wrappedError), \(wrappedError.userInfo)")
}
return coordinator
}()
lazy var masterManagedObjectContext: NSManagedObjectContext = {
let coordinator = self.persistentStoreCoordinator
let context = NSManagedObjectContext.init(concurrencyType: .privateQueueConcurrencyType)
context.persistentStoreCoordinator = coordinator
return context
}()
func saveMasterContext() {
masterManagedObjectContext.perform {
do {
try self.masterManagedObjectContext.save()
} catch {
let nserror = error as NSError
Rollbar.error(withMessage: "Unresolved saveMasterContext error \(nserror), \(nserror.userInfo)")
}
}
}
lazy var mainManagedObjectContext: NSManagedObjectContext = {
let context = NSManagedObjectContext.init(concurrencyType: .mainQueueConcurrencyType)
context.parent = self.masterManagedObjectContext
return context
}()
func saveMainContext() {
mainManagedObjectContext.perform {
do {
try self.mainManagedObjectContext.save()
self.saveMasterContext()
} catch {
let nserror = error as NSError
Rollbar.error(withMessage: "Unresolved saveMainContext error \(nserror), \(nserror.userInfo)")
}
}
}
lazy var temporaryWorkerContext: NSManagedObjectContext = {
let context = NSManagedObjectContext.init(concurrencyType: .privateQueueConcurrencyType)
context.parent = self.mainManagedObjectContext
return context
}()
func saveWorkerContext(context: NSManagedObjectContext) {
do {
try context.save()
self.saveMainContext()
} catch {
let nserror = error as NSError
Rollbar.error(withMessage: "Unresolved saveWorkerContext error \(nserror), \(nserror.userInfo)")
}
}
let ad = UIApplication.shared.delegate as! AppDelegate
// Old Core Data Stack only compatible with iOS 10+
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
/*
The persistent container for the application. This implementation
creates and returns a container, having loaded the store for the
application to it. This property is optional since there are legitimate
error conditions that could cause the creation of the store to fail.
*/
let container = NSPersistentContainer(name: "MyApp")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
// MARK: - Core Data Saving support
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
}
let ad = UIApplication.shared.delegate as! AppDelegate
let context = ad.persistentContainer.viewContext
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment