Skip to content

Instantly share code, notes, and snippets.

@reyandrey
Last active August 20, 2020 12:59
Show Gist options
  • Save reyandrey/c40443aa6c5b1cf159f1b4dc6b15fc70 to your computer and use it in GitHub Desktop.
Save reyandrey/c40443aa6c5b1cf159f1b4dc6b15fc70 to your computer and use it in GitHub Desktop.
Core Data stack
import Foundation
import CoreData
public class CoreDataStack {
//MARK: Constants
let kBundleId = "com.qwe.rty.uiop"
let kModelName = "model"
//MARK: Static Properties
public static let shared = CoreDataStack()
//MARK: Public Properties
public private(set) lazy var mainContext: NSManagedObjectContext = {
let context = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
context.parent = self.writeContext
return context
}()
//MARK: Private Properties
private lazy var model: NSManagedObjectModel = {
let bundle = Bundle(identifier: kBundleId)!
let url = bundle.url(forResource: kModelName, withExtension: "momd")!
return NSManagedObjectModel(contentsOf: url)!
}()
private lazy var psc: NSPersistentStoreCoordinator = {
let psc = NSPersistentStoreCoordinator(managedObjectModel: self.model)
let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent(kModelName + ".sqlite")
let description = NSPersistentStoreDescription()
description.shouldInferMappingModelAutomatically = true
description.shouldMigrateStoreAutomatically = true
description.url = url
description.type = NSSQLiteStoreType
description.shouldAddStoreAsynchronously = false
psc.addPersistentStore(with: description) { description, error in
if let error = error {
assertionFailure("Failed to add persistent store: \(error)")
}
}
return psc
}()
private lazy var writeContext: NSManagedObjectContext = {
let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
context.persistentStoreCoordinator = self.psc
return context
}()
//MARK: Constructors
private init() {}
}
//MARK: Public Methods
public extension CoreDataStack {
func getPrivateContext(automaticallyMergesChangesFromParent: Bool) -> NSManagedObjectContext {
let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
context.parent = mainContext
context.automaticallyMergesChangesFromParent = automaticallyMergesChangesFromParent
return context
}
func saveChanges() {
saveContext(mainContext) {
self.saveContext(self.writeContext)
}
}
}
//MARK: Private Methods
private extension CoreDataStack {
func saveContext(_ context: NSManagedObjectContext, onCompletion completionHandler: (() -> ())? = nil) {
context.perform {
if context.hasChanges {
do {
try context.save()
completionHandler?()
} catch {
print("Failed to save context \(context): \(error)")
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment