Pageable 1.0.1

Pageable 1.0.1

Mrigank Gupta 维护。



Pageable 1.0.1

  • mrigankgupta

Pageable

CI Status Version License Platform

目的

"分页,也称为分页,是将文档分成离散页面的过程,这些页面可以是电子页面或打印页面。"

它是服务器/客户端管理大型数据集的常见技术,将这些数据集分成称为页面的块进行分布。在当今,社交媒体客户端应用通过发明“无限滚动”对此进行了改进。

无限滚动允许用户连续加载内容,消除了用户明确操作的需求。应用加载一些初始数据,然后在用户到达可见内容的底部时加载剩余的数据。这些数据是分页的。

基本用法

那么如何使用这个库呢?其实很简单,只需按照以下步骤进行即可...

步骤 0

创建一个简单的 PageInteractor 对象。PageInteractor 在两个泛型类型上操作。

第一个泛型是 TextView/CollectionView 上显示的 Model 类型。

第二个泛型是为在模型数据中找出重复项而使用的唯一项的类型。默认情况下,如果不需要过滤或 Model 中没有唯一可识别的对象,则可以将其指定为 Any

 let pageInteractor: PageInteractor<Model, Any> = PageInteractor()

步骤 1

现在需要在 ViewDidLoad() 方法中设置 pageInteractor 实例,以获取第一页数据。

func setupPageInteractor() {
  // Require to provide instance of TableView/CollectionView
  pageInteractor.pageDelegate = self.tableView
  // NetworkManager is implementing PageableService protocol
  pageInteractor.service = networkManager
  pageInteractor.refreshPage()
}

override func viewDidLoad() {
   super.viewDidLoad()
   setupPageInteractor()
 }

步骤 2

TableView 将从 PageInteractor 请求项目数量。

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
     return pageInteractor.visibleRow()
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  // Fetch a cell of the appropriate type.
  if indexPath.row >= pageInteractor.count() {
       let loadingCell = tableView.dequeueReusableCell(withIdentifier: "loadingCell", for: indexPath)
       return loadingCell
   } else {
       let cell = tableView.dequeueReusableCell(withIdentifier: "cellTypeIdentifier", for: indexPath)
       let cellData = pageInteractor.item(for: indexPath.row)
       // Configure the cell’s contents.
       cell.textLabel!.text = cellData.name
       return cell
   }
}

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
   pageInteractor.shouldPrefetch(index: indexPath.row)
}

步骤 3

现在最重要的是向 PageInteractor 提供数据。这是通过实现 PagableService 协议来完成的。它包含两个方法。

protocol PagableService: class {
   func loadPage<Item: Decodable>(_ page: Int, completion: @escaping (PageInfo<Item>?) -> Void)
   func cancelAllRequests()
}

当 PageInteractor 的 refresh 方法被调用,无论是TableView 加载完毕还是通过 UIRefreshControl 拖动时,它会跟踪页面编号,并通过调用 loadPage<Item: Decodable>(_ page: Int, completion: @escaping (PageInfo<Item>?) -> Void) 来请求加载下一页。其中 page 表示要加载的下一页。一旦页面加载完成,需要返回 PageInfo 结构。

struct PageInfo<T> {
    var types: [T] // list of item returned from request
    var page: Int // current page
    var totalPageCount: Int // total page
}

下面将展示是如何实现的。

extension NetworkManager: PagableService {
   func loadPage<Item: Decodable>(_ page: Int, completion: @escaping (PageInfo<Item>?) -> Void) {
        var info: PageInfo<Item>?
        getNextPage(page: page) { (response) in
        // paginated response will have page number as well as total page
            switch response {
            case let .success(result):
                // Provide PageInfo Object from the response or nil in case no response
                info = PageInfo(types: result.types,
                                page: result.page,
                                totalPageCount: result.totalPageCount)
            case let .failure(err):
                print(err)
            }
            // Returning PageInfo Object from callback to PageInteractor
            completion(info)
        }
    }
    
    func cancelAllRequests() {
        cancelAll()
    }
}

高级用法

Pageable 提供了一些额外功能,如

  1. 可配置要从服务器获取的起始页面索引。
  2. 在加载列表中的附加项目时过滤重复项。
     If server has added new entry in previous page displayed in pagination,
     it results in repeat of last item in fetched new page.
     
     Displayed                      __1__        On Server
     ____________                 ____2_____
     |  __1__   |                |  __3__   |       1
     |  __2__   |                |  __4__   |       2
     |  __3__   |  +__10__ ==    |  __4__   |      10
     |____4_____|                |____5_____|       3
        __5__                       __6__
        __6__                       __7__
        __7__                       __8__   new fetch
        __8__                       __9__

如果需要过滤重复条目,则需要模型数据的唯一条目密钥路径。这可以在初始化器中设置或在之后设置。

let pageInteractor: PageInteractor<UserModel, Int> = PageInteractor(firstPage: 1, service: networkManager, keyPath: \UserModel.id)

示例

要运行示例项目,请首先克隆仓库,然后从 Example 目录中运行 pod install

需求

安装

Pageable 可以通过 CocoaPods 获取。要安装它,只需将以下行添加到您的 Podfile 文件中:

pod 'Pageable'

作者

mrigankgupta, [email protected]

许可协议

Pageable 在 MIT 许可协议下提供。更多详情请查阅 LICENSE 文件。