# PersistenceMiddleware ## Getting Started The persistence middleware package provides the following *SwiftRex* compatible components. - **Action** The `PersistenceAction` object is a generic action. `Element` is an object that can be saved, deleted, updated and requested by the middleware. If one of those actions fail, the error is represented by a `PersistenceError` object. A `Request` object contains details for a fetch request (e.g. a `NSFetchRequest`). ```swift public struct PersistenceAction where PersistenceError: Error { public static var cancelRequest: PersistenceAction public static func save(_ element: Element) -> PersistenceAction public static func delete(_ element: Element) -> PersistenceAction public static func request(_ request: Request) -> PersistenceAction } ``` - **State** The state is represented by a `PersistenceState` object. ```swift public struct PersistenceState where PersistenceError: Error { public var request: RequestState public var persist: ProcessState public var delete: ProcessState public enum RequestState { case initial case loading case failed(error: PersistenceError, request: Request) case received([Element]) case canceled } public enum ProcessState { case initial case processing case failed(error: PersistenceError, element: Element) case succeeded } } ``` - **Middleware** The middleware is only accessible through an object, which conforms to the `PersistenceController` protocol: ```swift public protocol PersistenceController { associatedtype PersistenceError: Error associatedtype Element associatedtype Request typealias Action = PersistenceAction typealias State = PersistenceState func savePublisher(for element: Element) -> AnyPublisher func deletePublisher(for element: Element) -> AnyPublisher func requestPublisher(for request: Request) -> AnyPublisher, PersistenceError> } public extension PersistenceController { public func makeMiddleware() -> AnyMiddleware } ``` **Sidenote**: The `makeMiddleware()` function in `PersistenceController` should reduce the amount of generics to specify, which would be otherwise required. For Example, the `CoreDataController` (see: *CoreDataMiddleware*) just has one generic type to specify. ```swift let controller = CoreDataController(NSPersistentContainer(name: "MusicDB")) let middleware = controller.makeMiddleware() ``` which is much easier to read, compared to ```swift let controller = CoreDataController(NSPersistentContainer(name: "MusicDB")) // Here: makeMiddleware(_ controller: CoreDataController) is globally accessible let middleware: AnyMiddleware< PersistenceAction, PersistenceAction, PersistenceState > = makeMiddleware(controller) ``` - **Reducer** Just like the middleware, the reducer is bound to a `PersistenceController` type as a static variable: ```swift public extension PersistenceController { public static func makeReducer() -> Reducer } ```