MrAlek / PagedArray

A Swift data structure for easier pagination

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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)
    }
}
commented

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.