对于怎样取消网络请求 之前有朋友也问我 当界面一出现的时候就要进行网络请求 然后切换界面时也要进行网络请求 这个时候要是用户两手指不停的点击不同的界面 那么每次点击都需要进行一次请求 如果请求不中断 那么服务器会不停的进行数据返回 甚至还会产生一些其他的问题 非常的不友好 那么怎么对网络请求进行中断 这也是我们今天要写的内容
新建一个实体类 叫SuperNetworkManager 在.h中声明一个网络请求方法 .m中实现该方法 使得所有请求都调用同一个方法 只是传入的参数不同而已
.h中代码如下:
#import <Foundation/Foundation.h>
#import "NetworkAddress.h"
#import <AFNetworking.h>
#import "ResultDesc.h"
/**
网络用到的的Block
@param res 网络请求返回的结果
*/
typedef void(^ResultDescBlock)(ResultDesc *res); //回调
@interface SuperNetworkManager : NSObject
/**
网络请求属性 该属性目的当网络还在进行中时 进行界面切换等操作 能够取消掉该请求
*/
@property (nonatomic, strong) NSURLSessionDataTask *task;
/**
需要进行网络请求调用的方法
@param parameters 传入的参数
@param resBlock 网络请求返回的结果
*/
- (void )fetchDataWithparameters:(NSDictionary *)parameters ResultDesc:(ResultDescBlock)resBlock;
/**
单例模式
@return 网络请求实体类的对象
*/
+ (SuperNetworkManager *)shareManager;
/**
取消网络请求
*/
- (void)networkCancle;
@end
.m中代码如下
#import "SuperNetworkManager.h"
@implementation SuperNetworkManager
+ (SuperNetworkManager *)shareManager
{
static SuperNetworkManager *manager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[SuperNetworkManager alloc] init];
});
return manager;
}
- (void)networkCancle
{
[self.task cancel];
}
- (void)fetchDataWithparameters:(NSDictionary *)parameters ResultDesc:(ResultDescBlock)resBlock{
ResultDesc *res = [[ResultDesc alloc]init];
if (ConnectEnabled == ConnectNot){
res.desc = @"当前网络不可用,请检查网络连接状态";
resBlock(res);
return ;
}
AFHTTPSessionManager *session = [AFHTTPSessionManager manager];
session.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
session.responseSerializer = [AFHTTPResponseSerializer serializer];
[session.requestSerializer willChangeValueForKey:@"timeoutInterval"];
session.requestSerializer.timeoutInterval = 10.f;
[session.requestSerializer didChangeValueForKey:@"timeoutInterval"];
self.task = [session POST:SERVERURL parameters:parameters success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject){
//对返回的值进行解析
id responseObj = [self parseJson:responseObject];
if ([responseObj isKindOfClass:[NSDictionary class]]){
responseObj = (NSDictionary *)responseObj;
}
//如果返回值为空 则网络异常 本来这个不用写的 因为当时测试有段时间公司早上9.30之前禁网发现登陆时返回值不存在 这也是特殊情况 偶然发现的 故此加上一个判断
if (!responseObj){
res.desc = @"网络异常"; //对异常描述进行手动标明异常情况
resBlock(res);
return ;
}
//给接收网络请求的数据进行赋值 该情况表示正常请求成功 但不表示一定能拿到需要的数据 可能服务器也会返回员工编号不能为空等desc说明 这里只是表示跟服务器进行了交互 服务器返回了数据
ResultDesc *res = [[ResultDesc alloc]init];
[res mj_setKeyValues:responseObj];
resBlock(res);
}failure:^(NSURLSessionDataTask *task, NSError *error){
if (error.code == -1001){ //当返回的状态码为-1001时 表示请求超时 手动标明异常情况
res.desc = @"请求超时";
}else{
res.desc = @"网络连接异常"; //其它失败情况 均手动标注为网络连接异常或服务器连接异常
}
resBlock(res);
}];
}
/**
对网络请求的数据进行解析
@param responseObject 网络请求拿到的数据
@return 解析后的数据
*/
- (id)parseJson:(id)responseObject{
NSError *error = nil;
id jsonObject;
if ([responseObject isKindOfClass:[NSData class]]) {
jsonObject = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:&error];
}
return jsonObject;
}
代码举例说明使用情况和方法
/**
界面即将出现
*/
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
NSDictionary *data_paramas = [NetworkAddress parametersWithDataParamsOjbect:@{} andMethod:@"app.test"];
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.view animated:YES];
hud.opacity = 0.7;
hud.mode = MBProgressHUDModeIndeterminate;
hud.labelText = @"请求测试...";
[hud show:YES];
[[SuperNetworkManager shareManager] fetchDataWithparameters:data_paramas ResultDesc:^(ResultDesc *res) {
[hud removeFromSuperview]; //移除网络请求提示框
if (res.success) { //请求成功 再进行成功操作 try catch包裹防止异常情况
@try {
}@catch (NSException *exception) {
}@finally{
}
}else{
[MBProgressHUD showError:res.desc];//请求不成功的描述
}
}];
}
/**
界面即将消失
*/
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[[SuperNetworkManager shareManager]networkCancle];//取消网络请求
}