本文主要是针对目前我们项目中使用的框架进行一个讲解,使用的框架是MVCS,网络请求用的是YTKNetwork,欢迎各位大佬在下方进行留言,因为现在项目可能要重构,我就是个小白,也没有具体的优化方案。
MVC就不过多的讲解了,我们只是在这个基础上添加了Service层,用来处理网路请求,以及回调的处理,参照的博客地址:
www.jianshu.com/p/8b0d06bd5… blog.csdn.net/wangyanchan…
我自己写了一demo,基本跟目前项目架构类似,目前遇到的问题就是controller里边好多回调方法以及初始化方法,模块之间耦合性太高了,就比如跳转登录页面,然后从登录页面返回的时候需要判断好多条件,每个条件执行的回调方法可能还不一致,不方便维护。demo效果图如下:
@interface HomeModel : ResponseModel @property (nonatomic, copy) NSString *iconImg; @property (nonatomic, copy) NSString *iconName; @property (nonatomic, copy) NSString *iconDesc; @property (nonatomic, assign) int type; @end 复制代码
其中ResponseModel 是继承自JSONModel的
主要是用来处理请求的,因为YTKNetwork的核心思想是把每一个请求都封装成一个类,然后通过service或者controller层进行调用
下边列一下每个类的作用,以及包括的方法:
Protocol用来初始化数据的方法,因为可能多个页面需要用到,所以写成协议
@protocol HomeDataProtocol <NSObject> - (void)initWithData:(id)data; - (void)initWithData:(id)data selectIndex:(NSIndexPath *)indexPath; @end 复制代码
这是点击cell对应的加和减的代理方法
@protocol HomeTableViewCellDelegate <NSObject> - (void)didClickPlusView:(UIButton *)plusView index:(NSInteger)index; - (void)didClickMinusView:(UIButton *)minusView index:(NSInteger)index; @end 复制代码
RequestService这个主要负责调用Request方法,里边可能会包含到首页模块中用到的方法
@implementation HomeRequestService + (void)requestWithUserId:(NSString *)userId complete:(void(^)(id result,NSError *error))complete{ HomeRequest *request = [[HomeRequest alloc] init]; request.userId = userId; [request requestComplete:^(BaseRequest * _Nonnull request) { /// 这里边可以直接处理request返回的结果,但是不应该去处理,因为解析的工作完全可以统一处理 [request handleRequestWithClass:NSArray.class withComplete:^(id _Nonnull model, NSError * _Nonnull error) { if (complete) { model = [HomeModel arrayOfModelsFromDictionaries:model error:&error]; complete(model,error); } }]; }]; } @end 复制代码
Request这个继承自YTKNetwork的请求,.m文件需要实现请求的二级路径、是否添加缓存、请求参数等等
@implementation HomeRequest - (BOOL)enableMockData{ /// 这是我们在猿题库的基础上自己定义了一个方法,是否加载本地的缓存 /// YES代表使用本地缓存,他会从本地查找HomeRequest.json文件进行解析,主要是为了测试数据源的修改 return YES; } - (NSString *)requestUrl{ /// 这是请求的二级路径,一级路径需要在程序启动进行配置 return @"XXXXX/XXXX/AA.do"; } - (YTKRequestMethod)requestMethod{ /// 这是请求的方式 return YTKRequestMethodPOST; } - (id)requestArgument{ /// 这是请求的参数 return @{@"userId":_userId}; } @end 复制代码
主要负责页面UI的展示,以及请求数据,包括代理方法的实现,由于代码量多,只列出部分代码
@interface HomeViewController () < UITableViewDelegate, UITableViewDataSource, HomeTableViewCellDelegate > @property (nonatomic, strong) UITableView *tableView; @property (nonatomic, strong) NSMutableArray *dataArray; @end - (void)requestData{ __weak typeof(self)weakSelf = self; [HomeRequestService requestWithUserId:@"test" complete:^(id _Nonnull result, NSError * _Nonnull error) { if (!error) { /// 初始化数据 [weakSelf.dataArray removeAllObjects]; [weakSelf.dataArray addObjectsFromArray:result]; [weakSelf.tableView reloadData]; }else{ /// 处理弹框或者什么的异常处理 } }]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ HomeTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; cell.selectionStyle = UITableViewCellSelectionStyleNone; cell.delegate = self; [cell initWithData:self.dataArray[indexPath.row] selectIndex:indexPath]; return cell; } /// 点击加的回调 - (void)didClickPlusView:(UIButton *)plusView index:(NSInteger)index{ HomeModel *model = self.dataArray[index]; model.type++; [self.tableView reloadRow:index inSection:0 withRowAnimation:UITableViewRowAnimationNone]; } - (UITableView *)tableView{ if (!_tableView) { _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; _tableView.delegate = self; _tableView.dataSource = self; _tableView.backgroundColor = [UIColor redColor]; [_tableView registerClass:[HomeTableViewCell class] forCellReuseIdentifier:identifier]; } return _tableView; } 复制代码
View层就不过的叙述,就是UITableViewCell的创建
BaseViewContoller 和ResponseModel 就不多数了,主要说下BaseRequest类,里边一共3个方法,是否加载本地缓存、发起请求、解析返回json
@interface BaseRequest : YTKRequest /// 这个方法是否使用本地缓存,true代表使用 - (BOOL)enableMockData; /// 最底层发起请求的方法 (所有请求都需要走这个方法) /// @param complete 返回结果 - (void)requestComplete:(void(^)(BaseRequest *request))complete; /// 最底层处理返回结果的方法 (所有返回结果都会走这个方法) /// @param clsName 需要处理的类 /// @param complete 返回结果 - (void)handleRequestWithClass:(id)clsName withComplete:(void(^)(id model,NSError *error))complete; @end 复制代码
至于实现的话就是调用YTKNetwork的方法和调用jsonModel的一个解析方法就不在过多叙述
1,项目架构还是比较清晰的,而且也很好理解,上手容易。
2,减少了好多判断,比如请求参数的判断,这个交给了YTKNetwork,返回数据解析的判断,这个交给了JSONModel,而且还可以针对某个请求单独添加缓存。
3,可以单独配置某个请求是否用本地json,在接口还未实现的时候可以提取开发,只要有结构即可。
1,如果页面UI复杂,事件交互也比较多,那么Controller层代码量会暴增加,大部分都是delegate方法和getter方法,目前正在考虑如何剥离。
2,项目类会比较多,因为每个请求都是一个单独的类,目前项目大概100个接口左右,光请求的类就100+还不算service层,这个随着项目变大不知道是否会有影响。
3,模块和模块之间的耦合度还是很高,目前的架构还不适合模块的解耦。
我来评几句
登录后评论已发表评论数()