iOS 数据请求之网络层和数据层
在移动端开发中免不了要发送网络请求数据,一直以来我都没有数据层这个概念,偶然一次机会看网络视频,从一位叫MJ的大神那里获得“数据层”这个概念,在网络请求之后进行数据解析的时候尝试了下,发现层次感非常强��,代码的可读性很高,因此Mark一下。与君共勉!
下面将展示一个*常见的开发中例子:请求*新的列表数据。方法一非常常见:通常我们在请求的这个方法里面会进行参数赋值、字典数组与模型数组的转换等,使得请求的方法里面代码量很大,可读性差。
而!方法二是采用数据层的思想,已经将网络请求与数据处理彻底分开。因为在控制器里面只需要后的*新的数据,而不管请求这个过程,所以将网络请求这部分代码单独地抽取出来在一个工具类里面实现,抽取后的方法只需要我们提供请求所需要的动态参数,然后通过block将我们所需要的数据传递过来,代码的可读性强。推荐使用。
*#pragma mark –获取*新的数据(方法一 传统方法)*
– (void)getNewData
{
NSMutableDictionary *paraDic = [NSMutableDictionary dictionary];
paraDic[@”access_token”] = [ZYAccountTool account].access_token;
if (self.status.count) {
paraDic[@”since_id”] = [self.status.firstObject idstr];
}
[ZYHttpTool get:@”https://api.weibo.com/2/statuses/friends_timeline.json” parameters:paraDic progress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
ZYLog(@”ZYHttpTool –>%@”,responseObject);
[self.tableView.mj_header endRefreshing];
// 字典数组
NSArray *dataArr = responseObject[@”statuses”];
NSArray *status = [ZYStatus mj_objectArrayWithKeyValuesArray:dataArr];
[self.status addObjectsFromArray:status];
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, status.count)];
// NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:status.count];
[self.status insertObjects:status atIndexes:indexSet];
[self.tableView reloadData];
} failure:^(NSURLSessionDataTask *task, NSError *error) {
}];
}
***#pragma mark –获取*新的数据(方法二 采用数据层思想的方法)***
– (void)otherMethodNewStatus
{
NSString *sinceId = nil;
if (self.status.count) {
sinceId = [self.status.firstObject idstr];
}
[ZYStatusTool newStatusWithSinceId:sinceId success:^(NSArray *modelArray) {
[self.tableView.mj_header endRefreshing];
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, modelArray.count)];
[self.status insertObjects:modelArray atIndexes:indexSet];
[self.tableView reloadData];
} failure:^(NSError *error) {
ZYLog(@”失败了”);
}];
}
由上面两段代码明显看出:方法二目的性强,可读性高!简洁明了。
下面再看看数据层的代码封装方法:
/**
* 请求更新的微博数据
sinceId:返回比这个更大的微博数据
success:请求成功的时候回调(statuses(ZYStatus模型))
failure:请求失败的时候回调,错误传递给外界
*/
+ (void)newStatusWithSinceId:(NSString *)sinceId
success:(void(^)(NSArray *modelArray))success
failure:(void(^)(NSError *error))failure
{
ZYStatusPara *para = [ZYStatusPara sharedManager];
para.access_token = [ZYAccountTool account].access_token;
if (sinceId) {
para.since_id = sinceId;
}
[ZYHttpTool get:@”https://api.weibo.com/2/statuses/friends_timeline.json” parameters:para.mj_keyValues progress:nil success:^(NSURLSessionDataTask *task, id responseObject) {
NSArray *dicArray = responseObject[@”statuses”];
NSArray *modelArray = [ZYStatus mj_objectArrayWithKeyValuesArray:dicArray];
//只要请求成功了,就通过上面两步对返回的数据responseObject进行处理得到模型数组,然后将模型数组作为参数传递出去给外界使用!!
if (success) {
success(modelArray);
}
} failure:^(NSURLSessionDataTask *task, NSError *error) {
if (failure) {
failure(error);
}
}];
}
//数据层,我们将那些固定的参数都在这里处理完毕,只提供那些动态的参数字段供调用的时候赋值。
下面再看看对网络层的封装:网络层直接通过第第三方开源库AFNetWorking进行二次封装,这样以后整个工程改动的地方小,减少对AFNetWorking的依赖。
/**
GET请求方式
@param URLString 请求的主URL
@param parameters 请求参数
@param progress 进度
@param success 成功的回调
@param failure 失败的回调
*/
+ (void)get:(NSString *)URLString
parameters:(id)parameters
progress:(void(^)(NSProgress *downloadProgress))progress
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
{
// 获取http请求管理者
AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];
[mgr GET:URLString parameters:parameters progress:^(NSProgress * _Nonnull downloadProgress) {
if (progress) {
progress(downloadProgress);
}
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if (success) {
success(task,responseObject);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (failure) {
failure(task, error);
}
}];
}