Git Product home page Git Product logo

dknetworking's Introduction

DKNetworking

基于 AFNetworking + YYCache 的二次封装,支持缓存策略的网络请求框架

Travis CocoaPods CocoaPods license FOSSA Status

DKNetworking

前言

网络层是 APP 架构的一个重要部分,苹果的 CFNetwork 框架极其难用,导致基于 CFN 的框架 ASI 已经放弃维护。后来苹果推出了 NSURLSession,许多开源的框架都是基于它进行封装,例如我选用的 AFNetworking,运行效率没有 ASI 高,使用比 ASI 简单。但是,从使用的角度来看,还需要继续封装。于是,我依赖于 AFN + YYCache + MJExtension 封装出了 DKNetworking 框架。

特点

  • DKNetworkSessionManager 对 AFHTTPSessionManager 进行封装,以便以后可以轻易换掉依赖的 AFN。封装一层底层方法,包括网络请求、文件上传、文件下载这三个方法。其中网络请求调用了 AFN 的私有 API,把 GET、POST、PUT、DELETE、PATCH 这五个方法封成了一个 request 方法。

  • 拥有 AFN 大部分常用功能,包括网络状态监听等,提供类方法和实例方法调用。

  • 根据 JavaWeb 中 HttpServlet 的设计**,把网络请求的回调封装成了 request 和 response 两个对象。

  • 支持界面多级缓存。

  • 支持链式调用。

  • 支持配合 RAC 框架使用链式调用,支持自定义信号的返回值。

  • 网络请求异常时,弹出异常信息界面,WebView 展示异常信息。

安装

支持 Cocoapods 安装

pod 'DKNetworking'

或者下载 Demo 项目

  • 将根目录下的 DKNetworking 和 Vendor 文件夹拉进项目,其中 Vendor 文件夹有 AFNetworking、MJExtension、YYCache 和 ReactiveCocoa,前三个是必须依赖的,ReactiveCocoa 是可选的。

  • 必须在 Target -> Build Phases -> Link Binary With Libraries 中添加 libsqlite3.0.tbd,这是 YYCache 框架所需的。

使用

绝大部分方法都可以直接看 DKNetworking.h 中的声明以及注释。

获取单例对象

DKNetworking *networking = [DKNetworking networkManager];

从 1.1.0 版本开始提供了一个单例对象宏 DKNetworkManager

DKN 配置

设置请求根路径

[DKNetworking setupBaseURL:@"https://m.sfddj.com/app/v1/"];

baseURL 的路径一定要有“/”结尾,设置后所有的网络访问都使用相对路径。

设置日志

开启日志打印
[DKNetworking openLog];
关闭日志打印
[DKNetworking closeLog];

设置缓存

设置缓存方式
/**
 设置缓存方式
 DKNetworkCacheTypeNetworkOnly : 只加载网络数据
 DKNetworkCacheTypeCacheNetwork : 先加载缓存,然后加载网络
 @param cacheType 缓存类型
 */
+ (void)setupCacheType:(DKNetworkCacheType)cacheType;
获取缓存大小
/**
 获取网络缓存的总大小 动态单位(GB,MB,KB,B)

 @return 网络缓存的总大小
 */
+ (NSString *)cacheSize;
清除缓存
[DKNetworkCache clearCache];

设置序列化格式

设置请求序列化格式
/**
 设置网络请求参数的格式 : 默认为二进制格式

 @param requestSerializer DKRequestSerializerJSON:JSON格式, DKRequestSerializerHTTP:二进制格式
 */
+ (void)setRequestSerializer:(DKRequestSerializer)requestSerializer;
设置响应反序列化格式
/**
 设置服务器响应数据格式 : 默认为JSON格式

 @param responseSerializer DKResponseSerializerJSON:JSON格式, DKResponseSerializerHTTP:二进制格式
 */
+ (void)setResponseSerializer:(DKResponseSerializer)responseSerializer;

设置请求超时时间

/**
 设置请求超时时间 : 默认10秒

 @param time 请求超时时长(秒)
 */
+ (void)setRequestTimeoutInterval:(NSTimeInterval)time;

设置 Header

/**
 设置请求头参数

 @param networkHeader 请求头参数字典
 */
+ (void)setNetworkHeader:(NSDictionary *)networkHeader;

设置 SessionManager

// 设置sessionManager,例如设置HTTPMethodsEncodingParametersInURI,让DELETE方法的请求参数放在Body中,而非URI中
[DKNetworking setupSessionManager:^(DKNetworkSessionManager *sessionManager) {
    sessionManager.requestSerializer.HTTPMethodsEncodingParametersInURI = [NSSet setWithObjects:@"GET", @"HEAD", nil];
}];

网络状态

监听网络状态

[DKNetworking networkStatusWithBlock:^(DKNetworkStatus status) {
    switch (status) {
        case DKNetworkStatusUnknown: // 网络状态未知
            break;
        case DKNetworkStatusNotReachable: // 无网络
            break;
        case DKNetworkStatusReachableViaWWAN: // 手机网络(蜂窝)
            break;
        case DKNetworkStatusReachableViaWiFi: // WIFI网络
            break;
    }
}];

获取当前网络状态

/**
 有网络:YES, 无网络:NO
 */
+ (BOOL)isNetworking;

/**
 手机网络:YES, 非手机网络:NO
 */
+ (BOOL)isWWANNetwork;

/**
 WiFi网络:YES, 非WiFi网络:NO
 */
+ (BOOL)isWiFiNetwork;

网络请求

常规调用

以 POST 方法为例,方法定义:

/**
 POST请求
 
 @param URL 请求地址
 @param parameters 请求参数
 @param callback 请求回调
 @return 返回的对象可取消请求,调用cancel方法
 */
+ (NSURLSessionTask *)POST:(NSString *)URL parameters:(NSDictionary *)parameters callback:(DKNetworkBlock)callback;
- (NSURLSessionTask *)POST:(NSString *)URL parameters:(NSDictionary *)parameters callback:(DKNetworkBlock)callback;

调用:

[DKNetworking POST:url parameters:@{@"name":@"bingo"} callback:^(DKNetworkRequest *request, DKNetworkResponse *response) {
    // ...
}];

链式调用

方法定义:

/** 链式调用 */
- (DKNetworking *(^)(NSString *url))get;
- (DKNetworking *(^)(NSString *url))post;
- (DKNetworking *(^)(NSString *url))put;
- (DKNetworking *(^)(NSString *url))delete;
- (DKNetworking *(^)(NSString *url))patch;
- (DKNetworking *(^)(NSDictionary *params))params;
- (DKNetworking *(^)(NSDictionary *header))header;
- (DKNetworking *(^)(DKNetworkCacheType cacheType))cacheType;
- (DKNetworking *(^)(DKRequestSerializer requestSerializer))requestSerializer;
- (DKNetworking *(^)(DKResponseSerializer responseSerializer))responseSerializer;
- (DKNetworking *(^)(DKRequestTimeoutInterval requestTimeoutInterval))requestTimeoutInterval;
- (void(^)(DKNetworkBlock networkBlock))callback;

调用:

DKNetworkManager.post(url).params(@{@"name":@"bingo"}).callback(^(DKNetworkRequest *request, DKNetworkResponse *response) {
    // ...
});

RAC 链式调用

方法定义:

在原链式方法的基础上补充了一个 executeSignal 方法,返回信号。

#ifdef RAC
/** RAC链式发送请求 */
- (RACSignal *)executeSignal;
#endif

调用:

[DKNetworkManager.post(url).params(@{@"name":@"bingo"}).executeSignal subscribeNext:^(RACTuple *x) {
    DKNetworkResponse *response = x.second;
    // ...
} error:^(NSError *error) {
    // ...
}];

RAC 链式调用 自定义信号的返回值

方法定义:

#ifdef RAC
/**
 设置响应结果回调,可以设置信号返回的value为自己想要的值,比如用MJExtension框架,将DKNetworkResponse对象的rawData字典转为自己项目的实体类再返回
 
 @param flattenMapBlock 结果映射的设置回调block,其中RACTuple的first为DKNetworkRequest对象,second为DKNetworkResponse对象
 */
+ (void)setupResponseSignalWithFlattenMapBlock:(DKNetworkFlattenMapBlock)flattenMapBlock;
#endif

使用:

考虑到代码执行顺序的问题,建议在项目中创建一个继承自 NSObject 的类 DKNetworkConfig,在 + load 方法中调用 DKN 的配置方法,设置回调的信号的 return 值,根据不同项目进行配置。

[DKNetworking setupResponseSignalWithFlattenMapBlock:^RACStream *(RACTuple *tuple) {
    DKNetworkResponse *response = tuple.second; // 框架默认返回的response
    MyHttpResponse *myResponse = [MyHttpResponse mj_objectWithKeyValues:response.rawData]; // 项目需要的response
    myResponse.rawData = response.rawData;
    myResponse.error = response.error;
    return [RACSignal return:RACTuplePack(tuple.first, myResponse)];
}];

调用:

经过上面的setupResponseSignalWithFlattenMapBlock:方法设置后,信号返回的 RACTuple 的 second 为自定义的 response 对象。

[DKNetworkManager.post(url).executeSignal subscribeNext:^(RACTuple *x) {
    //DKNetworkResponse *response = x.second;
    MyHttpResponse *myResponse = x.second;
    // ...
} error:^(NSError *error) {
    // ...
}];

取消请求

/**
 取消所有HTTP请求
 */
+ (void)cancelAllRequest;

/**
 取消指定URL的HTTP请求
 */
+ (void)cancelRequestWithURL:(NSString *)URL;

上传

上传文件
/**
 上传文件

 @param URL 请求地址
 @param parameters 请求参数
 @param name 文件对应服务器上的字段
 @param filePath 文件本地的沙盒路径
 @param progressBlock 上传进度回调
 @param callback 请求回调
 @return 返回的对象可取消请求,调用cancel方法
 */
+ (NSURLSessionTask *)uploadFileWithURL:(NSString *)URL
                             parameters:(NSDictionary *)parameters
                                   name:(NSString *)name
                               filePath:(NSString *)filePath
                          progressBlock:(DKNetworkProgressBlock)progressBlock
                               callback:(void(^)(DKNetworkResponse *response))callback;
上传图片
/**
 上传图片

 @param URL 请求地址
 @param parameters 请求参数
 @param name 图片对应服务器上的字段
 @param images 图片数组
 @param fileNames 图片文件名数组,传入nil时数组内的文件名默认为当前日期时间戳+索引
 @param imageScale 图片文件压缩比 范围 (0.f ~ 1.f)
 @param imageType 图片文件的类型,例:png、jpg(默认类型)....
 @param progressBlock 上传进度回调
 @param callback 请求回调
 @return 返回的对象可取消请求,调用cancel方法
 */
+ (NSURLSessionTask *)uploadImagesWithURL:(NSString *)URL
                               parameters:(NSDictionary *)parameters
                                     name:(NSString *)name
                                   images:(NSArray<UIImage *> *)images
                                fileNames:(NSArray<NSString *> *)fileNames
                               imageScale:(CGFloat)imageScale
                                imageType:(NSString *)imageType
                            progressBlock:(DKNetworkProgressBlock)progressBlock
                                 callback:(void(^)(DKNetworkResponse *response))callback;

下载

/**
 下载文件

 @param URL 请求地址
 @param fileDir 文件存储目录(默认存储目录为Download)
 @param progressBlock 文件下载的进度回调
 @param callback 请求回调,filePath为文件保存路径
 @return 返回 NSURLSessionDownloadTask 实例,可用于暂停继续,暂停调用 suspend 方法,开始下载调用 resume 方法
 */
+ (NSURLSessionTask *)downloadWithURL:(NSString *)URL
                              fileDir:(NSString *)fileDir
                        progressBlock:(DKNetworkProgressBlock)progressBlock
                             callback:(void(^)(NSString *filePath, NSError *error))callback;

TODO

  • 链式编程虽然好看一点,但是没有常规调用方便,不能像以往一样敲两个字母 Xcode 就智能补全整个方法,并且可能会出现 .get().post().get().post() 这种没有意义的链式调用的情况。

  • 用面向协议(接口)的函数式编程可以解决上面的问题,但是网络层工具的调用是可以没有顺序的,比如 .params().post().post().params() 应该是都可以的,这样的话会让协议很难制定,还是会出现上面的问题。

  • 与服务端的通讯加密,考虑添加 RSA 非对称加密等方法。

License

FOSSA Status

dknetworking's People

Contributors

bingozb avatar fossabot avatar swiftkings avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

dknetworking's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.