InfiniteKit 0.1.2

InfiniteKit 0.1.2

Maintained by Carl.

Depends on:
RxSwift~> 4.3
RxCocoa~> 4.3
RxDataSources~> 3.0
RxSwiftExt~> 3.0


Version License Platform


  • Create Infinite Scroll in declarative style with much less code
  • All states related UI covered by the library by default
  • Fully customizable
  • Well tested using RxTest


In real world iOS applications, most data from server are displayed with UITableView and UICollectionView. To create a full-featured infinite scroll using server data, developers should consider implementing many things:

  • Loading view: display when reload or first time load
  • Empty view: display when server returns empty data
  • Error view: display when network error occurs
  • Pull to refresh
  • Pull to load more

Most junior developers would build up the data flow repeatedly, which would eventually lead to code redundancy and duplicated test cases.
In most cases, Infinite scroll can be abstracted into a common pattern.
InfiniteKit exists to let developers use this pattern easily, create full-featured infinite scroll faster, and in declarative style.

Let's build up a infinite scroll to list github users using Github Open API:

Firstly, take a look the abstraction in InfiniteKit InfiniteList<Cell, DataPack, CellModel>:

  • Cell is subclass of UITableViewCell
  • DataPack represents data package receieved from server
  • CellModel should be extracted from DataPack and used to render cell

We declare necessary types:

typealias Cell = UITableViewCell
struct CellModel: Codable {
    let id: Int
    let login: String
typealias DataPack = (data: [CellModel], offset: Int)
typealias List = InfiniteList<Cell, DataPack, CellModel>

Next we declare how we gonna fetch data and use them to render our cells, with only four closures:

  • List.InitFetch
  • List.NextFetch
  • List.DataExtractor
  • List.CellDecorator

List.InitFetch is alias of () -> Single<DataPack>, generates first data fetch.

let initFetch: List.InitFetch = {
    let url = ""
    let req = genReq(url: url)
    return sendReq(req, decodeWith: [CellModel].self)
        .map { (data: $0, offset: $0.count) }

List.NextFetch is alias of (DataPack) -> Single<DataPack?>, generates data fetch based on the last fetched result, return nil if no more data is available.

let nextFetch: List.NextFetch = { lastDataPack in
    let url = ""
    let params = ["since": String(lastDataPack.offset)]
    let req = genReq(url: url, params: params)
    return sendReq(req, decodeWith: [CellModel].self)
        .map { (data: $0, offset: lastDataPack.offset + $0.count) }

List.DataExtractor is alias of ([DataPack]) -> [CellModel], to map data packs to cell models.

let dataExtractor: List.DataExtractor = { dataPacks in
    let flattened = { $ }.flatMap { $0 }
    // remove duplicate & order asc by id
    return Array(Set(flattened)).sorted(by: { $ < $ })

List.CellDecorator is alias of (Cell, CellModel) -> Void, to update cells using model.

let cellDecorator: List.CellDecorator = { cell, model in
    cell.textLabel?.text = model.login

We now can use this config to create our List, which is subclass of ViewController:

let config = List.Config(
    initFetch: initFetch,
    nextFetch: nextFetch,
    dataExtractor: dataExtractor,
    cellDecorator: cellDecorator
let list = List(config: config)

The List now has default Loading view, Empty view, Error view, Pull to refresh, Pull to load more, and the core data flow is well tested already by the library.

You can customize the List by configure List.Config

config.refreshControl // UIRefreshControl
config.loadingView // UIView
config.emptyViewAndReloadTrigger // (UIView, ControlEvent<()>)
config.errorViewAndReloadTrigger // (UIView, ControlEvent<()>)


  • InfiniteList
  • InfiniteSectionList
  • InfiniteCollection
  • InfiniteSecitonCollection


To run the example project, clone the repo, and run pod install from the example directory first.



InfiniteKit is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'InfiniteKit'


wddwycc, [email protected]


InfiniteKit is available under the MIT license. See the LICENSE file for more info.