import Combine import Disk import Foundation protocol FileStorage { func save(_ value: Value, as name: String) throws func savePublisher(_: Value, as name: String) -> AnyPublisher func retrieve(_ name: String, as type: Value.Type) throws -> Value func retrievePublisher(_: String, as type: Value.Type) -> AnyPublisher func append(_ newValue: Value, to name: String) throws func appendPublisher(_: Value, to name: String) -> AnyPublisher } final class BaseFileStorage: FileStorage { private let processQueue = DispatchQueue(label: "BaseFileStorage.processQueue") func save(_ value: Value, as name: String) throws { let encoder = JSONEncoder() encoder.outputFormatting = .prettyPrinted try Disk.save(value, to: .documents, as: name, encoder: encoder) } func savePublisher(_ value: Value, as name: String) -> AnyPublisher { Future { promise in self.processQueue.async { do { try self.save(value, as: name) promise(.success(())) } catch { promise(.failure(error)) } } } .eraseToAnyPublisher() } func retrieve(_ name: String, as type: Value.Type) throws -> Value { try Disk.retrieve(name, from: .documents, as: type) } func retrievePublisher(_ name: String, as type: Value.Type) -> AnyPublisher { Future { promise in self.processQueue.async { do { let value = try self.retrieve(name, as: type) promise(.success(value)) } catch { promise(.failure(error)) } } } .eraseToAnyPublisher() } func append(_ newValue: Value, to name: String) throws { try Disk.append(newValue, to: name, in: .documents) } func appendPublisher(_ newValue: Value, to name: String) -> AnyPublisher { Future { promise in self.processQueue.async { do { try self.append(newValue, to: name) promise(.success(())) } catch { promise(.failure(error)) } } } .eraseToAnyPublisher() } }