AutoCat2/AutoCatCore/Services/StorageService.swift

92 lines
2.7 KiB
Swift

import Foundation
import CoreData
protocol StorageServiceProtocol {
var context: NSManagedObjectContext { get }
func store(vehicle: Vehicle) throws -> CDVehicle
}
public class StorageService: StorageServiceProtocol {
private static var instance: StorageService?
private let container: NSPersistentCloudKitContainer
public static var shared: StorageService {
get async throws {
if let instance = StorageService.instance {
return instance
} else {
let service = StorageService(inMemory: Testing.isUITesting)
try await service.loadPersistentStores()
StorageService.instance = service
return service
}
}
}
public static var sharedNotWait: StorageService {
if let instance = StorageService.instance {
return instance
} else {
let service = StorageService(inMemory: Testing.isUITesting)
Task {
try? await service.loadPersistentStores()
}
StorageService.instance = service
return service
}
}
init(inMemory: Bool = false) {
let bundle = Bundle(for: Self.self)
let url = bundle.url(forResource: "AutoCat2", withExtension: "momd")
let mom = NSManagedObjectModel(contentsOf: url!)
container = NSPersistentCloudKitContainer(name: "AutoCat2", managedObjectModel: mom!)
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
}
private func loadPersistentStores() async throws {
try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Void, Error>) in
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
continuation.resume(throwing: error)
} else {
continuation.resume(returning: ())
}
})
}
}
private func save() throws {
guard context.hasChanges else {
return
}
do {
try context.save()
} catch {
context.rollback()
throw error
}
}
// MARK: - StorageServiceProtocol
public var context: NSManagedObjectContext {
container.viewContext
}
public func store(vehicle: Vehicle) throws -> CDVehicle {
let cdVehicle = CDVehicle(vehicle: vehicle, context: context)
try save()
return cdVehicle
}
}