|
16 | 16 |
|
17 | 17 | 1.3 [Subscribing a completing publisher](#subscribing-a-completing-publisher) |
18 | 18 |
|
19 | | -1.4 Batched/Paged list of elements |
| 19 | +1.4 [List loaded in batches](#list-loaded-in-batches) |
20 | 20 |
|
21 | 21 | 2. [**Installation**](#installation) |
22 | 22 |
|
@@ -104,14 +104,67 @@ Just([Person(name: "test"]) |
104 | 104 |
|
105 | 105 | This will keep the subscriber and the data source alive until you cancel the subscription manually or it is released from memory. |
106 | 106 |
|
107 | | -#### Batched/Paged list of elements |
| 107 | +#### List loaded in batches |
108 | 108 |
|
109 | | -A common pattern in list based views is to load a very long list of elements in "batches" or "pages". (The distinction being that pages imply ordered, equal-length batches.) |
| 109 | +A common pattern for list views is to load a very long list of elements in "batches" or "pages". (The distinction being that pages imply ordered, equal-length batches.) |
110 | 110 |
|
111 | | -**CombineDataSources** includes a data source allowing you to easily implement the batched list pattern called `BatchesDataSource`. |
| 111 | +**CombineDataSources** includes a data source allowing you to easily implement the batched list pattern called `BatchesDataSource` and a table view controller `TableViewBatchesController` which wraps loading items in batches via the said data source and managing your UI. |
| 112 | + |
| 113 | +In case you want to implement your own custom logic, you can use directly the data source type: |
| 114 | + |
| 115 | +```swift |
| 116 | +let input = BatchesInput( |
| 117 | + reload: resetSubject.eraseToAnyPublisher(), |
| 118 | + loadNext: loadNextSubject.eraseToAnyPublisher() |
| 119 | +) |
| 120 | + |
| 121 | +let dataSource = BatchesDataSource<String>( |
| 122 | + items: ["Initial Element"], |
| 123 | + input: input, |
| 124 | + initialToken: nil, |
| 125 | + loadItemsWithToken: { token in |
| 126 | + return MockAPI.requestBatchCustomToken(token) |
| 127 | + }) |
| 128 | +``` |
| 129 | + |
| 130 | +`dataSource` is controlled via the two inputs: |
| 131 | + |
| 132 | +- `input.reload` (to reload the very first batch) and |
| 133 | + |
| 134 | +- `loadNext` (to load each next batch) |
| 135 | + |
| 136 | + The data source has four outputs: |
| 137 | + |
| 138 | +- `output.$items` is the current list of elements, |
| 139 | + |
| 140 | +- `output.$isLoading` whether it's currently fetching a batch of elements, |
| 141 | + |
| 142 | +- `output.$isCompleted` whether the data source fetched all available elements, and |
| 143 | + |
| 144 | +- `output.$error` which is a stream of `Error?` elements where errors by the loading closure will bubble up. |
| 145 | + |
| 146 | +In case you'd like to use the provided controller the code is fairly simple as well. You use the standard table view items controller and `TableViewBatchesController` like so: |
| 147 | + |
| 148 | +```swift |
| 149 | +let itemsController = TableViewItemsController<[[String]]>(cellIdentifier: "Cell", cellType: UITableViewCell.self, cellConfig: { cell, indexPath, text in |
| 150 | + cell.textLabel!.text = "\(indexPath.row+1). \(text)" |
| 151 | +}) |
| 152 | + |
| 153 | +let tableController = TableViewBatchesController<String>( |
| 154 | + tableView: tableView, |
| 155 | + itemsController: itemsController, |
| 156 | + initialToken: nil, |
| 157 | + loadItemsWithToken: { nextToken in |
| 158 | + MockAPI.requestBatch(token: nextToken) |
| 159 | + } |
| 160 | +) |
| 161 | +``` |
| 162 | + |
| 163 | +`tableController` will set the table view data source, fetch items, and display cells with the proper animations. |
112 | 164 |
|
113 | 165 | ## Todo |
114 | 166 |
|
| 167 | +- [ ] much better README, pls |
115 | 168 | - [ ] use a @Published for the time being instead of withLatestFrom |
116 | 169 | - [ ] make the batches data source prepend or append the new batch (e.g. new items come from the top or at the bottom) |
117 | 170 | - [ ] cover every API with tests |
|
0 commit comments