Last active
December 6, 2018 21:56
-
-
Save JasonCanCode/0406ba9c864c7da669aadb5021dbd163 to your computer and use it in GitHub Desktop.
Generic generator of an NSManagedObjectContext for interacting with a CoreData database
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Try
NSPersistentContainer