mirror of
https://github.com/dscyrescotti/Memola.git
synced 2026-03-30 14:12:24 +02:00
110 lines
3.7 KiB
Swift
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)
|
|
}
|