Real working example
ArkadiYoskovitz opened this issue · comments
Hi,
This looks like a great idea but I'm having some difficulty hocking the code to a real web service
Could please publish a working example.
Hi,
please check the pull request from my repo: #12
My pull request adjust the existing example. But here is an example ViewController. The DataService realized with Alamofire. I hope that's help.
import UIKit
import PagedArray
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView! {
didSet {
self.tableView.dataSource = self
self.tableView.delegate = self
self.tableView.tableFooterView = UIView()
self.tableView.registerNib(TableViewCell.loadNib, forCellReuseIdentifier: TableViewCell.identifier)
}
}
private var pagedDatasource = PagedArray<Model>(count: 1, pageSize: 1, preloadMargin: 10) {
didSet {
if self.pagedDatasource.count > oldValue.count
{
self.tableView.reloadData()
}
}
}
// MARK: - View lifecycle
override func viewDidLoad() {
super.viewDidLoad()
self.pagedDatasource.delegate = self
}
// MARK: - Helper
private func proceedData(models: [Model], count: Int?, page: Int = 0) {
guard let count = count where count > self.pagedDatasource.count else
{
self.setupItemsToReload(page, models: models)
return
}
self.pagedDatasource = PagedArray<Model>(delegate: self, count: count, pageSize: models.count, preloadMargin: 10)
self.setupItemsToReload(page, models: models)
}
private func setupItemsToReload(page: Int, models: [Model]) {
self.pagedDatasource.setElements(models, pageIndex: page)
let indexes = self.pagedDatasource.indexes(page)
if let indexPathsToReload = self.visibleIndexPathsForIndexes(indexes)
{
self.tableView.reloadRowsAtIndexPaths(indexPathsToReload, withRowAnimation: .Automatic)
}
}
private func visibleIndexPathsForIndexes(indexes: Range<Int>) -> [NSIndexPath]? {
return tableView.indexPathsForVisibleRows?.filter { indexes.contains($0.row) }
}
}
// MARK: - PagedArrayDelegate
extension ViewController: PagedArrayDelegate {
func fetchPagedData(page: Int, completion: (() -> Void)) {
DataService.getPaged(page) { (result, count) -> Void in
switch result
{
case .Failure(let error): print("** Error Page \(page): \(error.localizedDescription)")
case .Success(let value): self.proceedData(value, count: count, page: page)
}
completion()
}
}
}
// MARK: - UITableViewDataSource
extension ViewController: UITableViewDataSource {
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.pagedDatasource.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
return tableView.dequeueReusableCellWithIdentifier(ItemTableViewCell.identifier, forIndexPath: indexPath)
}
}
// MARK: - UITableViewDelegate
extension PagedArrayViewController: UITableViewDelegate {
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return TableViewCell.cellHeight
}
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
// preloading
self.pagedDatasource.loadDataIfNeededForRow(indexPath.row)
// cell configure
guard let cell = cell as? TableViewCell, let model = self.pagedDatasource[indexPath.row] else { return }
cell.configureCell(model)
}
}
Well, this issue is still open and maybe for a good reason.
I'm also having trouble implementing PagedArray with real web service. And example for swift 3 would be much appreciated. I'm using a collectionView, but I guess it would be the same as for tableView.
@MrAlek could you please provide an example as @AFcgi did above but using latest syntax and current codebase ?
@staticdreams The reason I haven't provided an example is that there is so many different ways you could setup your collection view, table view, page view controller, etc, depending on your specific app architecture. This library is purposefully just a data structure, just like Array
, Set
or Dictionary
so that you can use it however you'd like in an application.
Personally, I use an approach very close to the demo where I map pages to network operations which returns model structs. Then the view controller listens to when the paged array changes and updates the table view by diffing the old array of optional models with the new one.
I might elaborate on it in a blog post but I think it's outside of the scope for this module.