AFNetworking 的二次封装(GET、POST、文件上传、文件下载、超时、HTTPS、请求头、取消网络请求)

  • .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

/**
 网络请求基础
 */
@interface SHRequestBase : NSObject

// 必填
//地址
@property (nonatomic, copy) NSString *url;

// 选填
//进度
@property (nonatomic, copy) void(^progress)(NSProgress *progress);
//成功
@property (nonatomic, copy) void (^success)(id responseObj);
//失败
@property (nonatomic, copy) void (^failure)(NSError *error);

//公共参数
//参数
@property (nonatomic, copy) id param;
//请求头
@property (nonatomic, copy) NSDictionary <NSString *, NSString *> *headers;
//请求标记
@property (nonatomic, copy) NSString *tag;
//重试次数
@property (nonatomic, assign) NSInteger retry;

#pragma mark GET
- (void)requestGet;

#pragma mark POST
- (void)requestPost;

#pragma mark FORM
- (void)requestFormWithFormParam:(id)formParam;

#pragma mark 文件上传(单个)
- (void)requestUploadFileWithName:(NSString *_Nullable)name
                     data:(NSData *)data;

#pragma mark 文件上传(多个 一次)
- (void)requestUploadFilesWithName:(NSString *_Nullable)name
                     datas:(NSArray< NSData * > *)datas;

#pragma mark 文件上传(多个 多次)
- (void)requestUploadFilesManyWithName:(NSString *_Nullable)name
                         datas:(NSArray< NSData * > *)datas;

#pragma mark 文件下载
- (void)requestDownLoadFlieWithFlie:(NSString *)file;

#pragma mark 获取请求队列
- (NSDictionary *)getRequestQueue;

#pragma mark 取消所有网络请求
- (void)cancelAllOperations;

#pragma mark 取消某个网络请求
- (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

//请求队列
static NSMutableDictionary *netQueueDic;
//默认超时
static NSInteger timeOut = 10;
//日志
static bool isLog = YES;

#pragma mark - 实例化请求对象
+ (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"];
        
        //网络监听
        [[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
            switch (status)
            {
                case AFNetworkReachabilityStatusReachableViaWWAN:
                    //只加载网络
                    mgr.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringCacheData;
                    break;
                case AFNetworkReachabilityStatusReachableViaWiFi:
                    //只加载网络
                    mgr.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringCacheData;
                    break;
                default:
                    //只加载本地
                    mgr.requestSerializer.cachePolicy = NSURLRequestReturnCacheDataDontLoad;
                    break;
            }
        }];
        
        //开始监听
        [[AFNetworkReachabilityManager sharedManager] startMonitoring];
        
        //请求队列
        netQueueDic = [[NSMutableDictionary alloc] init];
    });
    
    return mgr;
}

#pragma mark - 请求方法

#pragma mark GET
- (void)requestGet{
    
    // 获取对象
    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{
    // 获取对象
    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{
    // 获取对象
    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 文件上传(单个)
- (void)requestUploadFileWithName:(NSString *_Nullable)name
                             data:(NSData *)data{
    name = name ?: @"file.jpg";
    // 获取对象
    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 文件上传(多个 一次)
- (void)requestUploadFilesWithName:(NSString *_Nullable)name
                             datas:(NSArray< NSData * > *)datas{
    name = name ?: @"file.jpg";
    // 获取对象
    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 文件上传(多个 多次)
- (void)requestUploadFilesManyWithName:(NSString *_Nullable)name
                                 datas:(NSArray< NSData * > *)datas{
    name = name ?: @"file.jpg";
    
    // 获取对象
    AFHTTPSessionManager *mgr = [SHRequestBase manager];
    __block NSMutableDictionary *temp = [[NSMutableDictionary alloc] init];
    
    dispatch_group_t group = dispatch_group_create();
    
    //循环
    [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]];
    
    // 获取对象
    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];
        }
    }];
    //启动
    [task resume];
    [self handleTag:task];
}

#pragma mark 获取请求队列
- (NSDictionary *)getRequestQueue{
    return netQueueDic;
}

#pragma mark 取消所有网络请求
- (void)cancelAllOperations{
    NSDictionary *temp = [NSDictionary dictionaryWithDictionary:netQueueDic];
    
    [temp enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL *_Nonnull stop) {
        //取消网络请求
        [self cancelOperationsWithTag:key];
    }];
}

#pragma mark 取消某个网络请求
- (void)cancelOperationsWithTag:(NSString *)tag{
    if (tag)
    {
        //取消请求
        NSURLSessionTask *task = netQueueDic[tag];
        if (task)
        {
            [task cancel];
            //移除队列
            [netQueueDic removeObjectForKey:tag];
        }
    }
}

#pragma mark - 私有方法
#pragma mark 处理成功
- (void)handleSuccess:(id)responseObject{
    //移除队列
    [self cancelOperationsWithTag:self.tag];
    //打印
    if (isLog) {
        SHLog(@"地址:%@\n入参:%@\n回参:%@", self.url, self.param, responseObject);
    }
    //回调
    if (self.success) {
        self.success(responseObject);
    }
}

#pragma mark 处理失败
- (void)handleFailure:(NSError *)error{
    //移除队列
    [self cancelOperationsWithTag:self.tag];
    //打印
    if (isLog) {
        SHLog(@"地址:%@\n入参:%@\n回参:%@", self.url, self.param, error.description);
    }
    //回调
    if (self.success) {
        self.failure(error);
    }
}

#pragma mark 处理tag
- (void)handleTag:(NSURLSessionTask *)task{
    if (self.tag.length)
    {
        //添加队列
        netQueueDic[self.tag] = task;
    }
}

@end

使用

//请求
    SHRequestBase *request = [SHRequestBase new];
    request.url = url;
    request.param = param;
    weakify(self);
    request.success = ^(id  _Nonnull responseObj) {
        //处理数据
        SHRequestBaseModel *model = [SHRequestBaseModel mj_objectWithKeyValues:responseObj];
        [weak_self handleDataWithModel:model error:nil block:result];
    };
    request.failure = ^(NSError * _Nonnull error) {
        //处理数据
        [weak_self handleDataWithModel:nil error:error block:result];
    };
    [request requestGet];
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容