Files
Memola/Memola/Persistence/Core/Persistence.swift
2024-07-21 15:47:13 +07:00

110 lines
3.7 KiB
Swift

//
// Persistence.swift
// Memola
//
// Created by Dscyre Scotti on 5/4/24.
//
import CoreData
import Foundation
final class Persistence {
private let modelName = "MemolaModel"
static let shared: Persistence = Persistence()
private init() { }
lazy var viewContext: NSManagedObjectContext = {
persistentContainer.viewContext
}()
lazy var backgroundContext: NSManagedObjectContext = {
let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
context.parent = viewContext
context.undoManager = nil
context.automaticallyMergesChangesFromParent = true
return context
}()
var newBackgroundContext: NSManagedObjectContext {
let context = persistentContainer.newBackgroundContext()
context.undoManager = nil
context.automaticallyMergesChangesFromParent = true
return context
}
lazy var persistentContainer: NSPersistentContainer = {
let persistentStore = NSPersistentStoreDescription()
persistentStore.shouldMigrateStoreAutomatically = true
persistentStore.shouldInferMappingModelAutomatically = true
let container = NSPersistentContainer(name: modelName, managedObjectModel: managedObjectModel)
do {
let coordinator = container.persistentStoreCoordinator
if let oldStore = coordinator.persistentStores.first {
try coordinator.remove(oldStore)
}
_ = try coordinator.addPersistentStore(type: .sqlite, at: sqliteURL)
} catch {
fatalError("[Memola] - \(error.localizedDescription)")
}
container.persistentStoreDescriptions = [persistentStore]
container.loadPersistentStores { description, error in
if let error {
fatalError("[Memola]: \(error.localizedDescription)")
}
}
return container
}()
private lazy var managedObjectModel: NSManagedObjectModel = {
guard let modelURL = Bundle.main.url(forResource: modelName, withExtension: ".momd"), let model = NSManagedObjectModel(contentsOf: modelURL) else {
fatalError("[Memola]: Unable to load model.")
}
return model
}()
private lazy var sqliteURL: URL = {
do {
let fileURL = try FileManager.default.url(
for: .documentDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: true
).appendingPathComponent("\(modelName).sqlite")
NSLog(fileURL.absoluteString)
return fileURL
} catch {
fatalError("[Memola]: \(error.localizedDescription)")
}
}()
}
// MARK: - Global Method
func withPersistence(_ keypath: KeyPath<Persistence, NSManagedObjectContext>, _ task: @escaping (NSManagedObjectContext) throws -> Void) {
let context = Persistence.shared[keyPath: keypath]
context.perform {
do {
try task(context)
} catch {
NSLog("[Memola] - \(error.localizedDescription)")
}
}
}
func withPersistenceSync(_ keypath: KeyPath<Persistence, NSManagedObjectContext>, _ task: @escaping (NSManagedObjectContext) throws -> Void) {
let context = Persistence.shared[keyPath: keypath]
context.performAndWait {
do {
try task(context)
} catch {
NSLog("[Memola] - \(error.localizedDescription)")
}
}
}
func withPersistenceContext<T>(_ keypath: KeyPath<Persistence, NSManagedObjectContext>, _ task: @escaping (NSManagedObjectContext) throws -> T) throws -> T {
let context = Persistence.shared[keyPath: keypath]
return try task(context)
}