基于AFNetworking3.X的二次封装及拓展

AFN3.X其实已经很封装的很好了,但是做项目的时候,总是有情况需要对网络统一处理,比如说缓存策略、重复请求管理功能,这些AFN3.1都没有提供直接的方法;比如每次请求回来,都有可能存在异常,我们肯定不能在每个请求里都加判断,所以就基于AFNetworking之上做了一层封装,向业务层更加友好。

概述

ZBNetworking是一个集约型框架,发起请求集中在一个类上,统一管理,适合中小型的项目,需要对网路请求进行更加细致的配置和管理,这个网络框架就可能不太适合,如果是大项目可以看一下YTKNetwork。框架目录如下

基于AFNetworking3.X的二次封装及拓展_第1张图片
ZBN目录

重复请求

判断是否是同一个请求(依据是请求url和参数是否相同)

  1. GET:就判断请求的URL是否相同,
  2. POST:如果是POST请求,除了判断URL,还需判断请求体的内容是否相同(POST请求的参数放在HTTP body里);
- (BOOL)isTheSameRequest:(NSURLRequest *)request {
    if ([self.HTTPMethod isEqualToString:request.HTTPMethod]) {
        if ([self.URL.absoluteString isEqualToString:request.URL.absoluteString]) {
            if ([self.HTTPMethod isEqualToString:@"GET"] || [self.HTTPBody isEqualToData:request.HTTPBody]) {
                NSLog(@"同一个请求还没执行完,又来请求☹️");
                return YES;
            }
        }
    }
    return NO;
}

遍历ZBNetworking当前的运行任务(调动currentRunningTasks获取当前的运行任务),根据任务源请求判断是否已经有相同的请求正在执行当中:

- (BOOL)haveSameRequestInTasksPool:(ZBURLSessionTask *)task {
    __block BOOL isSame = NO;
    [[self currentRunningTasks] enumerateObjectsUsingBlock:^(ZBURLSessionTask *obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if ([task.originalRequest isTheSameRequest:obj.originalRequest]) {
            isSame  = YES;
            *stop = YES;
        }
    }];
    return isSame;
}

如果有重复请求,取消新请求

//判断重复请求,如果有重复请求,取消新请求
    if ([self haveSameRequestInTasksPool:session]) {
        [session cancel];
        return session;
    }

网络回调统一处理

可以在此方法里,根据业务需要添加判断

- (BOOL)networkResponseManage:(id)responseObject{
    NSData *data = nil;
    NSError *error = nil;
    if ([responseObject isKindOfClass:[NSData class]]) {
        data = responseObject;
    }else if ([responseObject isKindOfClass:[NSDictionary class]]){
        data = [NSJSONSerialization dataWithJSONObject:responseObject options:NSJSONWritingPrettyPrinted error:&error];
    }
    id json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
    NSLog(@"%@",json);
    
    //统一判断所有请求返回状态,例如:-2就强制更新
    int stat = 0;
    switch (stat) {
        case -1:{//强制退出
            return NO;
        }
            break;
        case -2:{//强制更新
            return NO;
        }
            break;
        case -3:{//弹出对话框
            return NO;
        }
            break;
        default:
            break;
    }
    return YES;
}

缓存设计

先说说如何启动我们的缓存机制,GET和POST的API有一个cache参数,它用于给大家决定是否开启缓存机制,你可以根据自己的需要来决定是否开启cache,即时性和时效性的数据建议不开启缓存,一般建议开启,开启缓存后会回调两次,第一次获取是缓存数据,第二次获取的是最新的网络数据

NSURLCache的局限性,需要基于HTTP缓存机制的缓存方案需要客户端和服务器双边配合。所以我学习SDWebImage的缓存方案分两级缓存:内存缓存和磁盘缓存,缓存的过程如下:

第一次请求获取相应数据,先缓存到内存,再缓存到磁盘,下一次再发起相同的请求时,会先查找内存之中会不会有相应的缓存,如果有则返回缓存数据,如果没有,则向磁盘查找,如果磁盘存在缓存则返回,否则发起网络请求获取数据。

上面就是缓存的整一个过程,思路还是比较清晰,除此之外,缓存的设计还需要考虑两个问题:

  1. 缓存的淘汰策略
  2. 缓存的过期机制

ZBCacheManager是一个缓存管理类,暴露出简单的API给XDNetworking进行缓存的存取,底层是使用ZBMemoryCache(NSCache)进行内存缓存,使用ZBDiskCache(NSFileManager)进行磁盘缓存,缓存淘汰策略采用LRU算法(ZBLRUManager)。它是一个单例,通过一个全局入口统一访问:

+ (ZBCacheManager *)shareManager;

默认是磁盘大小是50MB,有效期是7天,如果想自定义设置,可以通过以下方法设置:

- (void)setCacheTime:(NSTimeInterval) time diskCapacity:(NSUInteger) capacity;

API设计

GET请求

/**
 *  GET请求
 *
 *  @param url              请求路径
 *  @param cache            是否缓存
 *  @param params           拼接参数
 *  @param progressBlock    进度回调
 *  @param successBlock     成功回调
 *  @param failBlock        失败回调
 *
 *  @return 返回的对象中可取消请求
 */
- (ZBURLSessionTask *)getWithUrl:(NSString *)url
                           cache:(BOOL)cache
                          params:(NSDictionary *)params
                   progressBlock:(ZBGetProgress)progressBlock
                    successBlock:(ZBResponseSuccessBlock)successBlock
                       failBlock:(ZBResponseFailBlock)failBlock;

POST请求

/**
 *  POST请求
 *
 *  @param url              请求路径
 *  @param cache            是否缓存
 *  @param refresh          解释同上
 *  @param params           拼接参数
 *  @param progressBlock    进度回调
 *  @param successBlock     成功回调
 *  @param failBlock        失败回调
 *
 *  @return 返回的对象中可取消请求
 */
- (ZBURLSessionTask *)postWithUrl:(NSString *)url
                   refreshRequest:(BOOL)refresh
                            cache:(BOOL)cache
                           params:(NSDictionary *)params
                    progressBlock:(ZBPostProgress)progressBlock
                     successBlock:(ZBResponseSuccessBlock)successBlock
                        failBlock:(ZBResponseFailBlock)failBlock;

文件上传

/**
 *  文件上传
 *
 *  @param url              上传文件接口地址
 *  @param data             上传文件数据
 *  @param type             上传文件类型
 *  @param name             上传文件服务器文件夹名
 *  @param mimeType         mimeType
 *  @param progressBlock    上传文件路径
 *  @param successBlock     成功回调
 *  @param failBlock        失败回调
 *
 *  @return 返回的对象中可取消请求
 */
- (ZBURLSessionTask *)uploadFileWithUrl:(NSString *)url
                               fileData:(NSData *)data
                                   type:(NSString *)type
                                   name:(NSString *)name
                               mimeType:(NSString *)mimeType
                          progressBlock:(ZBUploadProgressBlock)progressBlock
                           successBlock:(ZBResponseSuccessBlock)successBlock
                              failBlock:(ZBResponseFailBlock)failBlock;

多文件上传

/**
 *  多文件上传
 *
 *  @param url           上传文件地址
 *  @param datas         数据集合
 *  @param type          类型
 *  @param name          服务器文件夹名
 *  @param mimeTypes      mimeTypes
 *  @param progressBlock 上传进度
 *  @param successBlock  成功回调
 *  @param failBlock     失败回调
 *
 *  @return 任务集合
 */
- (NSArray *)uploadMultFileWithUrl:(NSString *)url
                         fileDatas:(NSArray *)datas
                              type:(NSString *)type
                              name:(NSString *)name
                          mimeType:(NSString *)mimeTypes
                     progressBlock:(ZBUploadProgressBlock)progressBlock
                      successBlock:(ZBMultUploadSuccessBlock)successBlock
                         failBlock:(ZBMultUploadFailBlock)failBlock;

文件下载

/**
 *  文件下载
 *
 *  @param url           下载文件接口地址
 *  @param progressBlock 下载进度
 *  @param successBlock  成功回调
 *  @param failBlock     下载回调
 *
 *  @return 返回的对象可取消请求
 */
- (ZBURLSessionTask *)downloadWithUrl:(NSString *)url
                        progressBlock:(ZBDownloadProgress)progressBlock
                         successBlock:(ZBDownloadSuccessBlock)successBlock
                            failBlock:(ZBDownloadFailBlock)failBlock;

获取当前正在运行的任务

/**
 *  正在运行的网络任务
 *  @return task
 */
- (NSArray *)currentRunningTasks;

取消GET请求

/**
 *  取消GET请求
 */
- (void)cancelRequestWithURL:(NSString *)url;

取消所有请求

/**
 *  取消所有请求
 */
- (void)cancleAllRequest;

获取缓存大小

/**
 *  获取缓存大小
 *
 *  @return 缓存大小
 */
- (NSUInteger)totalCacheSize;

清除下载数据

/**
 *  清除下载数据
 */
- (void)clearDownloadData;

清除所有缓存

/**
 *  清除所有缓存
 */
- (void)clearTotalCache;

自动清理缓存

//每次网络请求的时候,检查此时磁盘中的缓存大小,阈值默认是50MB,如果超过阈值,则清理LRU缓
    //存,同时也会清理过期缓存,缓存默认SSL是7天,磁盘缓存的大小和SSL的设置可以通过该方法
    //[YQCacheManager shareManager] setCacheTime: diskCapacity:]设置。

    [[ZBCacheManager shareManager] clearLRUCache];

源码地址

https://github.com/biyuhuaping/ZBNetworking 喜欢的star呦~

文章参考学习了:http://www.jianshu.com/p/d0751b9a8d65

你可能感兴趣的:(基于AFNetworking3.X的二次封装及拓展)