# PersistenceMiddleware ## Getting Started The persistence middleware package provides the following *SwiftRex* compatible components. - **Action** The `PersistenceAction<Element, PersistenceError, Request>` 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<Element, PersistenceError, Request> 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<Element, PersistenceError, Request>` object. ```swift public struct PersistenceState<Element, PersistenceError, Request> 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<Element, PersistenceError, Request> typealias State = PersistenceState<Element, PersistenceError, Request> func savePublisher(for element: Element) -> AnyPublisher<Void, PersistenceError> func deletePublisher(for element: Element) -> AnyPublisher<Void, PersistenceError> func requestPublisher(for request: Request) -> AnyPublisher<PersistenceFetchResult<Element>, PersistenceError> } public extension PersistenceController { public func makeMiddleware() -> AnyMiddleware<Action, Action, State> } ``` **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<Song>(NSPersistentContainer(name: "MusicDB")) let middleware = controller.makeMiddleware() ``` which is much easier to read, compared to ```swift let controller = CoreDataController<Song>(NSPersistentContainer(name: "MusicDB")) // Here: makeMiddleware<Request>(_ controller: CoreDataController<Request>) is globally accessible let middleware: AnyMiddleware< PersistenceAction<Song, SongError, SongRequest>, PersistenceAction<Song, SongError, SongRequest>, PersistenceState<Song, SongError, SongRequest> > = 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<Action, State> } ```