好处:数据与VC层独立开来,结构清晰,方便处理;
缺点:一个VC对应一个viewModel
-
创建BaseViewModel基类
- block作为回调
typedef void(^QYRequestCompletedBlock)(BOOL success,NSString *error,BOOL hasMoreData,BOOL isBlank);
success:请求成功与否;
error:错误提示;
hasMoreData:能否上拉加载更多;
isBlank:数据是否为空;
typedef void(^QYCacheCompletedBlock)(BOOL success,NSString *error);
success:数据是否为空;
- 通用数据的定义
//vc直接读取dataArray
@property (nonatomic, strong) NSMutableArray *dataArray;
//true = 刷新; false = 加载更多
@property (nonatomic, assign) BOOL refresh;
///分页
@property (nonatomic, assign) NSInteger pageIndex;
@property (nonatomic, assign) NSInteger pageSize;
- 实现方法,改变的是pageIndex
- (void)loadLastestPage;//刷新pageIndex=0
- (void)loadNextPage;//加载下一页pageIndex++
//子类实现具体请求
- (void)loadItemsWithPageNum:(NSInteger)pageNum;
- 缓存的读取
-(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