美文网首页
iOS 中使用 protocol 来重构分页加载

iOS 中使用 protocol 来重构分页加载

作者: Ajcc | 来源:发表于2018-06-05 13:19 被阅读47次
    pages.png

    TableView 分页加载是我们在开发中最常遇到的一种需求,里面的逻辑并不复杂,但如何把他们写好,代码能够尽量多的复用起来就得下一点功夫了。
    在 Objective-C 中我们可能会通过继承来抽象分页的逻辑,但是从代码工程上是能不用继承就尽量不要使用。在 swfit 中我们可以利用 protocol 来很好的抽象这部分逻辑。
    首先我们需要定义分页的几个常用的属性,可用代码描述如下:

    protocol PullToRefreshable: DataSourceType {
    
        /// tableView 所用到的数据源
        var datas: Pages<Item>? { get set }
        
        /// 刷新的 view 可以是: UIScrollView/UITableView/UICollctionView
        var refreshView: UIScrollView { get }
        
        /// 刷新 API 地址,TargetType 同时封装了 `url`, `parameters`, `method`
        var refreshTarget: TargetType { get }
        
        func loadMore()
        
        func beginRefresh()
        
        /// 在此方法中调用 tableView.reloadData()
        func reloadData()
    }
    

    利用 Extension 我们可以默认实现请求网络的方法

    extension PullToRefreshable {
        func refresh() {
            Network.default.request(target: refreshTarget) {[weak self] (result) in
                self?.refreshView.mj_header.endRefreshing()
                switch result {
                case let .success(response):
                    // Added JSON Parser 
    
                    self?.reloadData()
                case .error(_, _):
                    break
                }
            }
        }
    }
    

    类似的其他方法都可以添加默认实现。

    最后我们如果哪个 tableView 需要实现分页,我们只要去 conform 这个 protocol 即可。代码大概长这样:

    extension MessageDetailViewController: PullToRefreshable {
        
        typealias Item = MessageDetail
        
        var refreshView: UIScrollView {
            return tableView
        }
        
        var refreshTarget: TargetType {
            return UserTarget.messgaeDetail(account_no: accountNo, page: 1)
        }
        
        func reloadData() {
            tableView.reloadData()
        }
    
    }
    

    是不是简单了很多呢?

    在这里很多同学会不明白分页最重要的 page 参数去哪里了呢?我们可以回到上面看下是不是有个 Pages 对象,在这里我们封装了分页相关的属性,在 loadMore 方法中请求的时候只要将参数 page 赋值成 nextPage 即可。

    struct Pages<T: Mappable>: Mappable {
        
        var currentPage: Int = 1
        var pageSize: Int = 20
        var totalPage: Int = 0
        var totalRecords: Int = 0
        
        var items: [T] = [T]()
        
        var nextPage: Int {
            return currentPage + 1
        }
        
        init?(map: Map) {}
        mutating func mapping(map: Map) {
            items                <- map["items"]
            currentPage          <- map["current_page"]
            pageSize             <- map["page_size"]
            totalPage            <- map["total_page"]
            totalRecords         <- map["total_records"]
        }
    }
    

    这里暂时提供了一种思路,部分代码已被省略,如果有其他更好的方式,希望多多交流。

    相关文章

      网友评论

          本文标题:iOS 中使用 protocol 来重构分页加载

          本文链接:https://www.haomeiwen.com/subject/injpsftx.html