我习惯于用viewModel做数据层

好处:数据与VC层独立开来,结构清晰,方便处理;
缺点:一个VC对应一个viewModel


  • 创建BaseViewModel基类
  1. block作为回调
typedef void(^QYRequestCompletedBlock)(BOOL success,NSString *error,BOOL hasMoreData,BOOL isBlank);
success:请求成功与否;
error:错误提示;
hasMoreData:能否上拉加载更多;
isBlank:数据是否为空;

typedef void(^QYCacheCompletedBlock)(BOOL success,NSString *error);
success:数据是否为空;
  1. 通用数据的定义
//vc直接读取dataArray
@property (nonatomic, strong) NSMutableArray *dataArray;

//true = 刷新; false = 加载更多
@property (nonatomic, assign) BOOL refresh;

///分页
@property (nonatomic, assign) NSInteger pageIndex;
@property (nonatomic, assign) NSInteger pageSize;
  1. 实现方法,改变的是pageIndex
- (void)loadLastestPage;//刷新pageIndex=0
- (void)loadNextPage;//加载下一页pageIndex++
//子类实现具体请求
- (void)loadItemsWithPageNum:(NSInteger)pageNum;
  1. 缓存的读取
-(void)getCacheDataWithPath:(NSString*)fileName {
    NSArray *array = [QYFileManager readArrayWithFileName:fileName];
    
    [self.dataArray addObjectsFromArray:array];
    
    !self.cacheCompletedBlock ?: self.cacheCompletedBlock(self.dataArray.count>0,nil);
}
  • 创建继承BaseViewModel的viewModel

具体的请求具体而论,可以添加筛选条件;

  • 具体方法
- (void)loadItemsWithPageNum:(NSInteger)pageNum {
    [super loadItemsWithPageNum:pageNum];
    
    kWeakSelf(self);
    [[QYNetManager sharedInstance] loadDataWithParameters:@{@"method":@"info",@"short_conn":@(0)} path:@"api/v1/vpan" methodType:QYRequestType_POST success:^(id responseObject) {
        kStrongSelf(self);
        
        if (pageNum == 0) {
            self.dataArray = nil;//初始化、忽略缓存
        }
        //TODO:数据的处理
        BOOL hasMoreData = true;//是否数据加载完毕
        
        //data...
        
        if (pageNum == 0) {
            //第一页数据缓存
            
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
                
                [QYFileManager saveArrayWithPath:self.dataArray fileName:@""];
            });
        }
        
        !self.requestCompletedBlock ?: self.requestCompletedBlock(true,nil,hasMoreData,self.dataArray.count>0);
    } failure:^(NSString *errorInfo) {
        kStrongSelf(self);
        
        !self.requestCompletedBlock ?: self.requestCompletedBlock(false,errorInfo,false,false);
    }];
    
}
  • VC调用

一个get方法

- (ViewControllerViewModel *)viewModel {
    if (!_viewModel) {
        _viewModel = [[ViewControllerViewModel alloc] init];
        
        __block ViewControllerViewModel *temp_viewModel = _viewModel;
        kWeakSelf(self);
        _viewModel.requestCompletedBlock = ^(BOOL success,NSString *error,BOOL hasMoreData,BOOL isBlank) {
            kStrongSelf(self);
            
            [self.tableView.mj_header endRefreshing];
            [self.tableView.mj_footer endRefreshing];
            
            if (success) {
                
                if (!hasMoreData) {//是否有更多数据
                    [self.tableView.mj_footer endRefreshingWithNoMoreData];
                }
                
                if (isBlank) {
                    //数据为空
                    //TODO:添加缺省页面
                }else {
                    if (temp_viewModel.refresh) {
                        //下拉上拉刷新
                    }else {
                        //上拉刷新
                    }
                }
            }else {
                //TODO:给出错误提示
            }
        };
        
        _viewModel.cacheCompletedBlock = ^(BOOL success,NSString *error) {
            //缓存
        };
        
    }
    return _viewModel;
}

注意的是每次下拉刷新的时候手动设置viewModel的refresh为YES

Demo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • iOS网络架构讨论梳理整理中。。。 其实如果没有APIManager这一层是没法使用delegate的,毕竟多个单...
    yhtang阅读 10,652评论 1 23
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,195评论 4 61
  • 2017.02.22 可以练习,每当这个时候,脑袋就犯困,我这脑袋真是神奇呀,一说让你做事情,你就犯困,你可不要太...
    Carden阅读 5,190评论 0 1
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,324评论 19 139
  • 冯粒粒那边已经热火朝天,两人不知是谁搂着谁。小东搀着她离开时,也亏她还记得还有个姐妹在这儿,对齐飞晃晃手,“哎帅哥...
    阿斤a阅读 1,469评论 0 0