Skip to content

Instantly share code, notes, and snippets.

@JasonCanCode
Last active December 6, 2018 21:56
Show Gist options
  • Save JasonCanCode/0406ba9c864c7da669aadb5021dbd163 to your computer and use it in GitHub Desktop.
Save JasonCanCode/0406ba9c864c7da669aadb5021dbd163 to your computer and use it in GitHub Desktop.
Generic generator of an NSManagedObjectContext for interacting with a CoreData database
import CoreData
/// Use `ContextGenerator.contextForDatabase(named:)` to generate an NSManagedObjectContext for interacting with CoreData
class ContextGenerator: NSObject {
class func contextForDatabase(named databaseName: String, inMemoryOnly: Bool = false) -> NSManagedObjectContext? {
return ContextGenerator.init(databaseName: databaseName, inMemoryOnly: inMemoryOnly)?.managedObjectContext
}
private let managedObjectContext: NSManagedObjectContext
private let managedObjectModel: NSManagedObjectModel
private let coordinator: NSPersistentStoreCoordinator
private init?(databaseName: String, inMemoryOnly: Bool) {
guard let modelURL = Bundle.main.url(forResource: databaseName, withExtension: "momd"),
let model = NSManagedObjectModel(contentsOf: modelURL),
let persistentCoordinator = ContextGenerator.coordinator(managedObjectModel: model, databaseName: databaseName) else {
return nil
}
let tempCoordinator = ContextGenerator.inMemoryCoordinator(managedObjectModel: model) ?? persistentCoordinator
let coordinator = inMemoryOnly
? tempCoordinator
: persistentCoordinator
let context = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.mainQueueConcurrencyType)
context.persistentStoreCoordinator = coordinator
self.managedObjectModel = model
self.coordinator = coordinator
self.managedObjectContext = context
super.init()
}
private static func coordinator(managedObjectModel: NSManagedObjectModel, databaseName: String) -> NSPersistentStoreCoordinator? {
guard let applicationDocumentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last else {
return nil
}
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel)
let url = applicationDocumentsDirectory.appendingPathComponent(databaseName + ".sqlite")
do {
let options = [
NSMigratePersistentStoresAutomaticallyOption: true,
NSInferMappingModelAutomaticallyOption: true
]
try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: options)
} catch {
print("Error creating persisitant store")
abort()
}
if FileManager.default.fileExists(atPath: url.path) {
do {
try FileManager.default.setAttributes([FileAttributeKey.protectionKey: FileProtectionType.complete], ofItemAtPath: url.path)
} catch {
print("cannot set NSFileProtectionComplete attribute")
}
}
return coordinator
}
private static func inMemoryCoordinator(managedObjectModel: NSManagedObjectModel) -> NSPersistentStoreCoordinator? {
let persistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: managedObjectModel)
do {
try persistentStoreCoordinator.addPersistentStore(ofType: NSInMemoryStoreType, configurationName: nil, at: nil, options: nil)
} catch {
print("Error creating persisitant store")
abort()
}
return persistentStoreCoordinator
}
}
@jwelch-mindgrub
Copy link

Try NSPersistentContainer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment