- .h文件
//
// SHRequestBase.h
// SHNetworkRequest
//
// Created by CSH on 2019/5/31.
// Copyright ? 2019 CSH. All rights reserved.
//
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
/**
網(wǎng)絡(luò)請求基礎(chǔ)
*/
@interface SHRequestBase : NSObject
// 必填
//地址
@property (nonatomic, copy) NSString *url;
// 選填
//進(jìn)度
@property (nonatomic, copy) void(^progress)(NSProgress *progress);
//成功
@property (nonatomic, copy) void (^success)(id responseObj);
//失敗
@property (nonatomic, copy) void (^failure)(NSError *error);
//公共參數(shù)
//參數(shù)
@property (nonatomic, copy) id param;
//請求頭
@property (nonatomic, copy) NSDictionary <NSString *, NSString *> *headers;
//請求標(biāo)記
@property (nonatomic, copy) NSString *tag;
//重試次數(shù)
@property (nonatomic, assign) NSInteger retry;
#pragma mark GET
- (void)requestGet;
#pragma mark POST
- (void)requestPost;
#pragma mark FORM
- (void)requestFormWithFormParam:(id)formParam;
#pragma mark 文件上傳(單個(gè))
- (void)requestUploadFileWithName:(NSString *_Nullable)name
data:(NSData *)data;
#pragma mark 文件上傳(多個(gè) 一次)
- (void)requestUploadFilesWithName:(NSString *_Nullable)name
datas:(NSArray< NSData * > *)datas;
#pragma mark 文件上傳(多個(gè) 多次)
- (void)requestUploadFilesManyWithName:(NSString *_Nullable)name
datas:(NSArray< NSData * > *)datas;
#pragma mark 文件下載
- (void)requestDownLoadFlieWithFlie:(NSString *)file;
#pragma mark 獲取請求隊(duì)列
- (NSDictionary *)getRequestQueue;
#pragma mark 取消所有網(wǎng)絡(luò)請求
- (void)cancelAllOperations;
#pragma mark 取消某個(gè)網(wǎng)絡(luò)請求
- (void)cancelOperationsWithTag:(NSString *)tag;
@end
NS_ASSUME_NONNULL_END
- .m文件
//
// SHRequestBase.m
// SHNetworkRequest
//
// Created by CSH on 2019/5/31.
// Copyright ? 2019 CSH. All rights reserved.
//
#import "SHRequestBase.h"
#import "AFHTTPSessionManager.h"
@implementation SHRequestBase
//請求隊(duì)列
static NSMutableDictionary *netQueueDic;
//默認(rèn)超時(shí)
static NSInteger timeOut = 10;
//日志
static bool isLog = YES;
#pragma mark - 實(shí)例化請求對(duì)象
+ (AFHTTPSessionManager *)manager
{
static AFHTTPSessionManager *mgr;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
mgr = [AFHTTPSessionManager manager];
mgr.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",
@"text/json",
@"text/javascript",
@"text/html",
@"text/plain",
@"multipart/form-data",
nil];
mgr.securityPolicy.allowInvalidCertificates = YES;
mgr.securityPolicy.validatesDomainName = NO;
mgr.requestSerializer.timeoutInterval = timeOut;
mgr.requestSerializer = [AFHTTPRequestSerializer serializer];
mgr.responseSerializer = [AFJSONResponseSerializer serializer];
[mgr.requestSerializer setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
//網(wǎng)絡(luò)監(jiān)聽
[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
switch (status)
{
case AFNetworkReachabilityStatusReachableViaWWAN:
//只加載網(wǎng)絡(luò)
mgr.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringCacheData;
break;
case AFNetworkReachabilityStatusReachableViaWiFi:
//只加載網(wǎng)絡(luò)
mgr.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringCacheData;
break;
default:
//只加載本地
mgr.requestSerializer.cachePolicy = NSURLRequestReturnCacheDataDontLoad;
break;
}
}];
//開始監(jiān)聽
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
//請求隊(duì)列
netQueueDic = [[NSMutableDictionary alloc] init];
});
return mgr;
}
#pragma mark - 請求方法
#pragma mark GET
- (void)requestGet{
// 獲取對(duì)象
AFHTTPSessionManager *mgr = [SHRequestBase manager];
// 開始請求
NSURLSessionDataTask *task = [mgr GET:self.url
parameters:self.param
headers:self.headers
progress:self.progress
success:^(NSURLSessionDataTask *_Nullable task, id _Nullable responseObject) {
//處理
[self handleSuccess:responseObject];
}
failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nullable error) {
if (self.retry > 0)
{
//重新請求
self.retry--;
[self requestGet];
}
else
{
[self handleFailure:error];
}
}];
[self handleTag:task];
}
#pragma mark POST
- (void)requestPost{
// 獲取對(duì)象
AFHTTPSessionManager *mgr = [SHRequestBase manager];
// 開始請求
NSURLSessionDataTask *task = [mgr POST:self.url
parameters:self.param
headers:self.headers
progress:self.progress
success:^(NSURLSessionDataTask *_Nullable task, id _Nullable responseObject) {
//處理
[self handleSuccess:responseObject];
}
failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nullable error) {
if (self.retry > 0)
{
//重新請求
self.retry--;
[self requestGet];
}
else
{
[self handleFailure:error];
}
}];
[self handleTag:task];
}
#pragma mark FORM
- (void)requestFormWithFormParam:(id)formParam{
// 獲取對(duì)象
AFHTTPSessionManager *mgr = [SHRequestBase manager];
// 開始請求
NSURLSessionDataTask *task = [mgr POST:self.url
parameters:self.param
headers:self.headers
constructingBodyWithBlock:^(id< AFMultipartFormData > _Nullable formData) {
NSError *error = nil;
NSData *data = [NSJSONSerialization dataWithJSONObject:formParam options:NSJSONWritingPrettyPrinted error:&error];
if (!error)
{
[formData appendPartWithFormData:data name:@"items"];
}
else
{
[self handleFailure:error];
}
}
progress:self.progress
success:^(NSURLSessionDataTask *_Nullable task, id _Nullable responseObject) {
[self handleSuccess:responseObject];
}
failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nullable error) {
if (self.retry > 0)
{
//重新請求
self.retry--;
[self requestFormWithFormParam:formParam];
}
else
{
[self handleFailure:error];
}
}];
[self handleTag:task];
}
#pragma mark 文件上傳(單個(gè))
- (void)requestUploadFileWithName:(NSString *_Nullable)name
data:(NSData *)data{
name = name ?: @"file.jpg";
// 獲取對(duì)象
AFHTTPSessionManager *mgr = [SHRequestBase manager];
// 開始請求
NSURLSessionDataTask *task = [mgr POST:self.url
parameters:self.param
headers:self.headers
constructingBodyWithBlock:^(id< AFMultipartFormData > _Nullable formData) {
if (data)
{
NSArray *temp = [name componentsSeparatedByString:@"."];
if (temp.count != 2)
{
temp = @[ name, @"jpg" ];
}
[formData appendPartWithFileData:data name:temp[0] fileName:[NSString stringWithFormat:@"file.%@", temp[1]] mimeType:@"application/octet-stream"];
}
}
progress:self.progress
success:^(NSURLSessionDataTask *_Nullable task, id _Nullable responseObject) {
[self handleSuccess:responseObject];
}
failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nullable error) {
if (self.retry > 0)
{
//重新請求
self.retry--;
[self requestUploadFileWithName:name data:data];
}
else
{
[self handleFailure:error];
}
}];
[self handleTag:task];
}
#pragma mark 文件上傳(多個(gè) 一次)
- (void)requestUploadFilesWithName:(NSString *_Nullable)name
datas:(NSArray< NSData * > *)datas{
name = name ?: @"file.jpg";
// 獲取對(duì)象
AFHTTPSessionManager *mgr = [SHRequestBase manager];
// 開始請求
NSURLSessionDataTask *task = [mgr POST:self.url
parameters:self.param
headers:self.headers
constructingBodyWithBlock:^(id< AFMultipartFormData > _Nullable formData) {
[datas enumerateObjectsUsingBlock:^(NSData *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
NSArray *temp = [name componentsSeparatedByString:@"."];
if (temp.count != 2)
{
temp = @[ name, @"jpg" ];
}
[formData appendPartWithFileData:obj name:temp[0] fileName:[NSString stringWithFormat:@"file.%@", temp[1]] mimeType:@"application/octet-stream"];
}];
}
progress:self.progress
success:^(NSURLSessionDataTask *_Nullable task, id _Nullable responseObject) {
[self handleSuccess:responseObject];
}
failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nullable error) {
if (self.retry > 0)
{
//重新請求
self.retry--;
[self requestUploadFilesWithName:name datas:datas];
}
else
{
[self handleFailure:error];
}
}];
[self handleTag:task];
}
#pragma mark 文件上傳(多個(gè) 多次)
- (void)requestUploadFilesManyWithName:(NSString *_Nullable)name
datas:(NSArray< NSData * > *)datas{
name = name ?: @"file.jpg";
// 獲取對(duì)象
AFHTTPSessionManager *mgr = [SHRequestBase manager];
__block NSMutableDictionary *temp = [[NSMutableDictionary alloc] init];
dispatch_group_t group = dispatch_group_create();
//循環(huán)
[datas enumerateObjectsUsingBlock:^(NSData *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
dispatch_group_enter(group);
// 開始請求
[mgr POST:self.url
parameters:self.param
headers:self.headers
constructingBodyWithBlock:^(id< AFMultipartFormData > _Nullable formData) {
NSArray *temp = [name componentsSeparatedByString:@"."];
if (temp.count != 2)
{
temp = @[ name, @"jpg" ];
}
[formData appendPartWithFileData:obj name:temp[0] fileName:[NSString stringWithFormat:@"file.%@", temp[1]] mimeType:@"application/octet-stream"];
}
progress:self.progress
success:^(NSURLSessionDataTask *_Nullable task, id _Nullable responseObject) {
dispatch_group_leave(group);
//存起來
[temp setValue:responseObject forKey:[NSString stringWithFormat:@"%lu", (unsigned long)idx]];
}
failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nullable error) {
*stop = YES;
dispatch_group_leave(group);
[self handleFailure:error];
}];
}];
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
[self handleSuccess:temp];
});
}
#pragma mark 文件下載
- (void)requestDownLoadFlieWithFlie:(NSString *)file{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:self.url]];
// 獲取對(duì)象
AFHTTPSessionManager *mgr = [SHRequestBase manager];
//開始請求
NSURLSessionDownloadTask *task = [mgr downloadTaskWithRequest:request
progress:self.progress
destination:^NSURL *_Nullable(NSURL *_Nullable targetPath, NSURLResponse *_Nullable response) {
return [NSURL fileURLWithPath:file];
}
completionHandler:^(NSURLResponse *_Nullable response, NSURL *_Nullable filePath, NSError *_Nullable error) {
if (error)
{
if (self.retry > 0)
{
//重新請求
self.retry--;
[self requestDownLoadFlieWithFlie:file];
}
else
{
[self handleFailure:error];
}
}
else
{
[self handleSuccess:filePath];
}
}];
//啟動(dòng)
[task resume];
[self handleTag:task];
}
#pragma mark 獲取請求隊(duì)列
- (NSDictionary *)getRequestQueue{
return netQueueDic;
}
#pragma mark 取消所有網(wǎng)絡(luò)請求
- (void)cancelAllOperations{
NSDictionary *temp = [NSDictionary dictionaryWithDictionary:netQueueDic];
[temp enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL *_Nonnull stop) {
//取消網(wǎng)絡(luò)請求
[self cancelOperationsWithTag:key];
}];
}
#pragma mark 取消某個(gè)網(wǎng)絡(luò)請求
- (void)cancelOperationsWithTag:(NSString *)tag{
if (tag)
{
//取消請求
NSURLSessionTask *task = netQueueDic[tag];
if (task)
{
[task cancel];
//移除隊(duì)列
[netQueueDic removeObjectForKey:tag];
}
}
}
#pragma mark - 私有方法
#pragma mark 處理成功
- (void)handleSuccess:(id)responseObject{
//移除隊(duì)列
[self cancelOperationsWithTag:self.tag];
//打印
if (isLog) {
SHLog(@"地址:%@\n入?yún)ⅲ?@\n回參:%@", self.url, self.param, responseObject);
}
//回調(diào)
if (self.success) {
self.success(responseObject);
}
}
#pragma mark 處理失敗
- (void)handleFailure:(NSError *)error{
//移除隊(duì)列
[self cancelOperationsWithTag:self.tag];
//打印
if (isLog) {
SHLog(@"地址:%@\n入?yún)ⅲ?@\n回參:%@", self.url, self.param, error.description);
}
//回調(diào)
if (self.success) {
self.failure(error);
}
}
#pragma mark 處理tag
- (void)handleTag:(NSURLSessionTask *)task{
if (self.tag.length)
{
//添加隊(duì)列
netQueueDic[self.tag] = task;
}
}
@end
使用
//請求
SHRequestBase *request = [SHRequestBase new];
request.url = url;
request.param = param;
weakify(self);
request.success = ^(id _Nonnull responseObj) {
//處理數(shù)據(jù)
SHRequestBaseModel *model = [SHRequestBaseModel mj_objectWithKeyValues:responseObj];
[weak_self handleDataWithModel:model error:nil block:result];
};
request.failure = ^(NSError * _Nonnull error) {
//處理數(shù)據(jù)
[weak_self handleDataWithModel:nil error:error block:result];
};
[request requestGet];