一般情况下,我们的网络请求可能是这样写的
- (void)getActivityWithPage:(NSInteger)pageNum
Size:(NSInteger)size
Type:(NSInteger)type
Latitude:(NSNumber*)latitude
Longitude:(NSNumber*)Longitude
Success:(SuccessFinishedBlock)success
Failture:(FailtureFinishedBlock)failture;
实现部分可能是这样(判断网络状态的我就省略了哈,项目中,是需要加上网络状态判断的)
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:baseUrl]];
manager.requestSerializer.timeoutInterval = 10.f;
NSMutableDictionary *para = [NSMutableDictionary dictionary];
//设置需要传递的参数para
[manager GET:kPEActivity parameters:para progress:^(NSProgress * _Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//这里,大部分就是转成自己的model,可以直接用MJExtension,很方便的
success(model);//存储数据成功的model
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"%@",error);
failture(error);
}];
不同的页面,会有很多不同的请求,我们就要一个一个去写类似的方法,当然,这样的好处是,通过请求名字,就可以知道是哪个请求,对数据的处理,也有很大的自由度。
一般情况下,如果后台是一个有点经验的,返回的数据格式都是固定的,我们在请求成功里边的处理,也是有很多重复的代码,这种情况,就需要封装了,可以这样写:
- (void)universalNetworkRequestWithNetConnectType:(RequestType)type requestURL:(NSString *)url model:(Class)modelClass para:(NSDictionary *)para success:(SuccessBlock)success successCodeError:(SuccessBlock)successCodeError fail:(DefeatedBlock)fail netError:(NetworkError)netError;
解释一下参数,RequestType:定义的请求方式枚举(get post等)。model:如果数据请求成功,需要将数据转化成这个model。para:请求参数。success:数据请求成功(根据后台的返回码来确定)。successCodeError:网络请求成功,但是返回的数据不是你要的数据(比如数据正确是200,但是有时候根据业务需求,会返回别的码,比如你在别的地方登录了什么的)。fail:网络请求失败。netError:没有网络。
方法实现部分:
if ([RNetStatus networkIsAvailable]) {
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:para];
switch (type) {
case get:
[self getNetworkRequestWithNetConnectRequestURL:url model:modelClass para:dic success:success successCodeError:successCodeError fail:fail];
break;
case post:
[self postNetworkRequestWithNetConnectRequestURL:url model:modelClass para:dic success:success successCodeError:successCodeError fail:fail];
break;
case upload:
//上传暂时没写,后期会补上
break;
}
}else{
netError();
}
根据不同的方法,来调afn响应的方法,这里,我只写出一个get请求的实现,post是一样的
- (void)getNetworkRequestWithNetConnectRequestURL:(NSString *)url model:(Class)model_class para:(NSDictionary *)para success:(SuccessBlock)success successCodeError:(SuccessBlock)successCodeError fail:(DefeatedBlock)fail{
[self.sessinoManager GET:url parameters:para progress:^(NSProgress * _Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
REFLog(@"--request success --%@--para is --%@", responseObject, para);
if ([responseObject[@"resCode"] intValue] == 200) {
if (model_class == nil) {
success(responseObject[@"data"]);
}else{
//如果data是数组,并且只有一层数据结构
if ([responseObject[@"data"] isKindOfClass:[NSArray class]]) {
NSArray *result = [model_class mj_objectArrayWithKeyValuesArray:responseObject[@"data"]];
success(result);
}else{//data直接就是一个字典
success([model_class mj_objectWithKeyValues:responseObject[@"data"]]);
}
}
}else{
successCodeError(responseObject[@"resMsg"]);
}
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
fail(error);
}];
}
解释一下代码:
如果model不是nil,意思就是得到的数据,可以转化成model,这里,就只是处理了返回的数据直接能转化成model,或者返回的数据是个数组,数组里存的就是字典。如果数据层级很多,这个方法是不适用的,或者写出一个单独的处理数据的函数来处理也是可以的,毕竟层级很多的数据,不是太多。
这里的sessionManager,是一个AFHTTPSessionManager的属性,可以这样懒加载一下
- (AFHTTPSessionManager *)sessinoManager {
if (!_sessinoManager) {
_sessinoManager = [[AFHTTPSessionManager manager] initWithBaseURL:base_URL];
_sessinoManager.requestSerializer.timeoutInterval = kTimeOut;
}
return _sessinoManager;
}
直接设置baseurl和超时时间。
使用的时候,可以这样
[[REFNetworkManager manager] universalNetworkRequestWithNetConnectType:get requestURL:@"" model:[Model class] para:@{@"":@""}success:^(id response) {
[SVProgressHUD dismiss];
} successCodeError:^(id response) {
[SVProgressHUD showSuccessWithString:response];
[refreshComponent endRefreshing];
} fail:^(NSError *error) {
[SVProgressHUD showNetTimeout];
} netError:^{
[SVProgressHUD showNetWorkError];
}];
这里,可以自己对SVProgressHUD进行一个简单的封装,用起来也是很方便的。
至于这里边的单利,block之类的,就不一一写出来了,不会的可以自行百度,很简单。