Blade
is a pagination framework that simplifies the integration of pagination into the application.
Blade provides two libraries for working with pagination: Blade
and BladeTCA
. BladeTCA
is an extension designed for working with Composable Architecture. Both support working with offset and cursor-based paginations.
First, you need to implement page loader for whether cursor or offset based pagination:
import Blade
/// Offset pagination loader
final class OffsetPageLoader<Element: Equatable & Decodable>: IOffsetPageLoader {
func loadPage(request: OffsetPaginationRequest) async throws -> Page<Element> {
// Implementation here
}
}
/// Cursor pagination loader
final class CursorPageLoader<Element: Equatable & Decodable & Identifiable>: ICursorPageLoader {
func loadPage(request: CursorPaginationRequest<Element>) async throws -> Page<Element> {
// Implementation here
}
}
Second, create a Paginator
instance:
import Blade
/// Offset-based pagination
let paginator = Paginator(configuration: PaginationLimitOffset(firstPage: .zero, limit: 20), offsetPageLoader: OffsetPageLoader())
/// Cursor-based pagination
let paginator = Paginator(configuration: PaginationCursorSeek(id: #id_here), offsetPageLoader: CursorPageLoader())
Third, the paginator is capable of requesting the first page, the next page, and resetting its state, like this:
/// Request an initial page
let page = try await paginator.refresh()
/// Request next page
let nextPage = try await paginator.nextPage()
/// Reset state
await paginator.reset()
If your app uses the Composable Architecture, Blade
can be easily integrated.
import BladeTCA
// MARK: Reducer
@Reducer
struct SomeFeature {
// MARK: Types
struct State: Equatable {
var paginator: PaginatorState<ArticleView.ViewModel>
}
enum Action {
case child(PaginatorAction<ArticleView.ViewModel, Never>)
}
// MARK: Reducer
var body: some ReducerOf<Self> {
Reduce { state, action in
switch state {
case .clild:
return .none
}
}
.paginator(
state: \SomeFeature.State.paginator,
action: /SomeFeature.Action.child,
loadPage: { request, state in
// Load page here
}
)
}
}
// MARK: View
import ComposableArchitecture
import SwiftUI
// MARK: - SomeView
struct SomeView: View {
// MARK: Properties
private let store: StoreOf<SomeFeature>
// MARK: Initialization
init(store: StoreOf<SomeFeature>) {
self.store = store
}
// MARK: View
var body: some View {
PaginatorListView(
store: store.scope(state: \.paginator, action: { .child($0) })
) { state in
// Implement UI here
}
}
- iOS 13.0+ / macOS 10.15+ / tvOS 13.0+ / watchOS 7.0+ / visionOS 1.0+
- Xcode 15.0
- Swift 5.7
The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift
compiler. It is in early development, but blade
does support its use on supported platforms.
Once you have your Swift package set up, adding blade
as a dependency is as easy as adding it to the dependencies
value of your Package.swift
.
dependencies: [
.package(url: "https://github.com/space-code/blade.git", .upToNextMajor(from: "1.0.0"))
]
- If you found a bug, open an issue.
- If you have a feature request, open an issue.
- If you want to contribute, submit a pull request.
Bootstrapping development environment
make bootstrap
Please feel free to help out with this project! If you see something that could be made better or want a new feature, open up an issue or send a Pull Request!
Nikita Vasilev, [email protected]
blade is available under the MIT license. See the LICENSE file for more info.