Skip to content

Latest commit

 

History

History
84 lines (75 loc) · 3.72 KB

File metadata and controls

84 lines (75 loc) · 3.72 KB

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).

    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.

    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:

    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.

    let controller = CoreDataController<Song>(NSPersistentContainer(name: "MusicDB"))
    let middleware = controller.makeMiddleware()

    which is much easier to read, compared to

    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:

    public extension PersistenceController {
        public static func makeReducer() -> Reducer<Action, State>
    }