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() 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) 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 } }