基于AF的二次封装FrankNetworkManage

对于iOS程序猿来说,AFNetworking的强大之处,自然是不用言表,大家都早已深有体会。但是一般在使用这些第三方的时候,我们一般都会根据自己的使用习惯及业务功能需求进行封装处理,当然我也一样,对AFNetworking进行了二次封装处理,所以此次发布出来仅供参考:

注意:使用该框架前,需要集成 AFNetworking 和 FMDB,因为该框架是基于这两者进行的二次封装

一:框架特点

1:基于AFNetworking封装处理,简化了对AFNetworking的直接操作,使调用更加方便简洁;
2:将AFNetworking原有的两种回调方式拓展为了三种回调,并且支持用户根据服务器数据格式进行配置,功能细化,操作简单;
3:结合FMDB封装了数据库,可以根据需要进行缓存网络数据;
4:集成了DelegateBlock两种网络回调方式,用户可以根据自己的喜好进行选择使用任意一种回调方式;

Demo链接:https://github.com/Kinglions/FrankNetworkManage

二:框架解析

基于AF的二次封装FrankNetworkManage_第1张图片
框架截图.png

(1)网络请求框架:

/**
 *  网络请求封装
 */

#import 
#import 
#import 
#import 
#import "FrankNetworkMacro.h"

typedef void (^RequestPrepare)();
typedef void (^RequestFinally)();

/**
 请求成功回调

 @param task 请求对象
 @param responseObject 响应数据
 @param requestParams 请求参数
 */
typedef void (^ReplySucess)(NSURLSessionDataTask *task, id responseObject, NSDictionary* requestParams);

/**
 请求失败回调
 */
typedef void (^ReplyFailure)(NSURLSessionDataTask *task, id responseObject, NSDictionary* requestParams);
/**
 请求错误回调
 */
typedef void (^ReplyError)(NSError *error, NSURLSessionDataTask *task, NSDictionary* requestParams);
/*  上传进度
 *
 *  @param bytesWritten              已上传的大小
 *  @param totalBytesWritten         总上传大小
 */
typedef void (^ReplyUploadProgress)(int64_t bytesWritten,int64_t totalBytesWritten);

typedef void (^MultipartData)(id  formData);

/**
 基础网络请求 其他的请求统一由此类发出

 - HTTP_REQUEST_METHOD_GET:
 - HTTP_REQUEST_METHOD_HEAD:
 - HTTP_REQUEST_METHOD_POST:
 - HTTP_REQUEST_METHOD_PUT:
 - HTTP_REQUEST_METHOD_PATCH:
 - HTTP_REQUEST_METHOD_DELETE:
 */
typedef NS_ENUM(NSUInteger, HTTP_REQUEST_METHOD) {
    
    HTTP_REQUEST_METHOD_GET = 0,
    HTTP_REQUEST_METHOD_HEAD,
    HTTP_REQUEST_METHOD_POST,
    HTTP_REQUEST_METHOD_PUT,
    HTTP_REQUEST_METHOD_PATCH,
    HTTP_REQUEST_METHOD_DELETE,
};

/**
 网络请求缓存处理

 - NetworkCacheType_Never: 重不进行缓存处理
 - NetworkCacheType_OnlyCache: 只进行缓存,但是不读取
 - NetworkCacheType_CacheAndLoad: 进行缓存,并且请求数据时先进行加载缓存,本次请求数据,下次加载
 */
typedef NS_ENUM(NSUInteger, NetworkCacheType) {
    
    NetworkCacheType_Never = 0,
    NetworkCacheType_OnlyCache,
    NetworkCacheType_CacheAndLoad,

};

@interface FrankNetworkManage : NSObject

/**
 *  创建单例对象
 */
+(instancetype)shareManager;

/**
 网络数据的缓存处理类型
 */
@property (nonatomic,assign)NetworkCacheType cacheType;

/**
 *  判断请求时是否需要 hud
 */
@property (nonatomic, assign) BOOL isShowHUD;

/**
 *  请求之前的准备,可直接调用本类对象的 prepare
 */
@property (nonatomic, copy) RequestPrepare prepare;

/**
 *  一个网络请求返回后做清理。
 */
@property (nonatomic,copy) RequestFinally finally;
/**
 *  网络请求返回成功
 */
@property (nonatomic, copy) ReplySucess sucess;

/**
 *  失败
 */
@property (nonatomic, copy) ReplyFailure failure;
/**
 *  请求出错
 */
@property (nonatomic, copy) ReplyError error;

/**
 共外界调用配置 判断逻辑【根据服务器返回值进行配置,可以在 Appdelegate 中进行设置】
 *
 *  @return YES 表示数据正确,NO 表示后台的错误提示,证明返回有误
 */
@property (nonatomic,copy) BOOL (^judgeResponseIsSuccess)(id responseSuccess);
/*
 *
 *  用于指定网络请求接口的基础url,如:
 *  http://www.baudu.com
 *  通常在AppDelegate中启动时就设置一次就可以了。
    如果接口有来源于多个服务器,可以调用更新
 *
 *
 *  @param baseUrl 网络接口的基础url
 */
+ (void)updateBaseUrl:(NSString *)baseUrl;
/*
 *  对外公开可获取当前所设置的网络接口基础url
 *
 *  @return 当前基础url
 */
+ (NSString *)baseUrl;
/**
 进行编码
 */
+ (NSString *)encodeUrl:(NSString *)url;
/**
 自动判断 baseurl 并进行组合 url
 */
+ (NSString *)absoluteUrlWithPath:(NSString *)path;


/**
 *  统一网络请求
 *
 *  @param method      请求类型(直接调用 枚举)
 *  @param urlString    请求URLString
 *  @param headerParams 请求头添加的参数
 *  @param params       请求参数
 *  @param finally      请求结束,进行清理(直接调用)
 *  @param sucess       请求成功,数据正常
 *  @param failure      请求失败
 *  @param netError      请求连接错误
 */
+(void)httpRequestWithHttpMethod:(HTTP_REQUEST_METHOD)method
                       urlString:(NSString *)urlString
                    headerParams:(NSDictionary *)headerParams
                          params:(id)params
                         finally:(RequestFinally)  finally
                          sucess:(ReplySucess)   sucess
                         failure:(ReplyFailure)  failure
                           error:(ReplyError)netError;




/*
 *
 *  开启或关闭是否自动将URL使用UTF8编码,用于处理链接中有中文时无法请求的问题
 *
 *  @param shouldAutoEncode YES or NO,默认为NO
 */
+ (void)shouldAutoEncodeUrl:(BOOL)shouldAutoEncode;


/*
 *  图片上传接口,若不指定baseurl,可传完整的url
 *
 *  @param image            图片对象
 *  @param url              上传图片的接口路径,如/path/images/
 *  @param filename     给图片起一个名字,默认为当前日期时间,格式为"yyyyMMddHHmmss",后缀为`jpg`
 *  @param name             与指定的图片相关联的名称,这是由后端写接口的人指定的,如imagefiles
 *  @param mimeType     默认为image/jpeg
 *  @param parameters   参数
 *  @param progress     上传进度
 *  @param success      上传成功回调
 *  @param fail             上传失败回调
 *
 *  @return
 */

+ (void)uploadWithImage:(UIImage *)image
                    url:(NSString *)url
               filename:(NSString *)filename
                   name:(NSString *)name
               mimeType:(NSString *)mimeType
             parameters:(NSDictionary *)parameters
               progress:(ReplyUploadProgress)progress
                success:(ReplySucess)success
                   fail:(ReplyError)fail;

/**
 *  上传文件操作
 *
 *  @param url                      上传路径
 *  @param uploadingFile    待上传文件的路径
 *  @param progress         上传进度
 *  @param success              上传成功回调
 *  @param fail                 上传失败回调
 *
 */
+ (void)uploadFileWithUrl:(NSString *)url
            uploadingFile:(NSString *)uploadingFile
                 progress:(ReplyUploadProgress)progress
                  success:(ReplySucess)success
                     fail:(ReplyError)fail;

其中需要注意的是@property (nonatomic,copy) BOOL (^judgeResponseIsSuccess)(id responseSuccess)属性,这个是根据后台的数据格式配置请求结果判断的回调,只需要在AppDelegate中进行配置一次就行。例如:

基于AF的二次封装FrankNetworkManage_第2张图片
配置示例.png

(2)网络下载框架:

#import "FrankNetworkManage.h"

/**
 断点下载

 - DownloadStatus_ResumingDown: 开始下载
 - DownloadStatus_SuspendDown: 暂停下载
 */
typedef NS_ENUM(NSInteger ,DownloadStatus) {
    
    DownloadStatus_ResumingDown = 0,
    DownloadStatus_SuspendDown = 1,

};

@interface FrankHttpDownloadManage : FrankNetworkManage

/** AFNetworking断点下载(支持离线)需用到的属性 **********/
/** 
 文件的总长度
 */
@property (nonatomic,assign,readonly) NSInteger fileLength;
/** 
 当前下载长度
 */
@property (nonatomic,assign,readonly) NSInteger currentLength;

/**
 下载文件保存路径
 */
@property (nonatomic,copy,readonly)NSString * downSavePath;


/**
 *  下载文件操作
 *
 *  @param url                      下载地址
 *  @param saveName               保存文件名字
 *  @param progressBlock            下载进度
 *  @param success                  下载成功回调
 *  @param failure                  下载失败回调
 */
- (instancetype)initWithDownloadUrl:(NSString *)url
             saveName:(NSString *)saveName
               progress:(ReplyUploadProgress)progressBlock
                success:(ReplySucess)success
                failure:(ReplyError)failure;
/**
 下载状态
 
 - DownloadStatus_SuspendDown: 暂停下载
 - DownloadStatus_ResumingDown: 开始下载
 
 */
-(void)setDownloadStatus:(DownloadStatus)status;

@end

(3)请求类BaseModel类 :

这个类是为了方便使用,而创建的一个基类框架,相当于在ViewControllerFrankNetworkManage中间添加的一层,用于处理数据交互相关逻辑,所以后期创建具体请求类只需要集成该BaseRequestHttpModel类,重写父类方法即可。
代码解析:

#import 
#import "FrankNetworkMacro.h"

/**
 请求成功时返回的数据

 @param models 数据模型
 */
typedef void(^SuccessModel)(id models);


/**
 代理方式下的 网络请求结果状态

 - ResponseHttpType_Success: 请求成功
 - ResponseHttpType_Failure: 请求失败
 - ResponseHttpType_NetworkError: 网络异常
 */
typedef NS_ENUM(NSInteger,ResponseHttpType) {
    ResponseHttpType_Success,
    ResponseHttpType_Failure,
    ResponseHttpType_NetworkError,
};
/**
 代理方式下的 网络请求类型,枚举回调区分
 */
typedef NS_ENUM(NSInteger,BusinessHttpType) {
    
    BusinessHttpType_None = 0,// 默认状态
    BusinessHttpType_LoadWeather ,// 请求天气
    
    // 此处可以根据自己的工程需求进行添加枚举分类。。。
};

#pragma mark -------- 通过 代理 方式处理请求回调,当使用 block 方式处理时,可以忽略代理  ---------
@protocol BaseRequestHttpModelDelegate 

@optional
/**
 *  为了降低耦合性,通过这个协议方法可以在对请求状态进行判断
 *
 *  @param type      判断是哪一类发送的请求
 *  @param retStatus 请求成功失败的状态
 */
- (void)DoneBusiness:(enum BusinessHttpType)type status:(ResponseHttpType)retStatus;

@end


@interface BaseRequestHttpModel : NSObject


/**
 请求地址
 */
@property (nonatomic,strong)NSString * urlStr;

/**
 请求头数据字典
 */
@property (nonatomic,strong)NSMutableDictionary * headerParams;

/**
 网络请求失败回调
 */
@property (nonatomic,copy)ReplyFailure failureBlock;
/**
 网络错误回调
 */
@property (nonatomic,copy)ReplyError networkerrBlock;

#pragma mark -------- 通过 代理 方式处理请求回调  ---------
#pragma mark -------- 通过 代理 方式处理请求回调  ---------

/**
 设置网络请求代理【当使用 block 方式处理时,可以忽略代理】
 */
@property (nonatomic,weak)id delegate;
/**
 网络请求API类型
 */
@property (nonatomic,assign) BusinessHttpType businessType;
/**
 告知当前网络处理状态
 */
-(void)doneBusiness:(ResponseHttpType)returnStatus;



/**
 供子类调用 【  代理方式请求调用方法  】
 
 @param method 请求方式
 @param params 请求参数数据
 @param isNeedHeader 是否需要 请求头数据
 */
-(void)doRequestWithHttpMethod:(HTTP_REQUEST_METHOD)method
                        params:(id)params
            isNeedHeaderParams:(BOOL)isNeedHeader;

#pragma mark -------- 通过 block 方式处理请求回调  ---------
#pragma mark -------- 通过 block 方式处理请求回调  ---------

/**
 供子类调用 【  代理方式请求调用方法  】
 
 @param method 请求方式
 @param params 请求参数数据
 @param isNeedHeader 是否需要 请求头数据
 @param success 成功回调数据模型
 @param fail 失败回调
 @param errorBlock 链接错误回调
 */
-(void)doRequestWithHttpMethod:(HTTP_REQUEST_METHOD)method
                        params:(id)params
        isNeedHeaderParams:(BOOL)isNeedHeader
                   success:(SuccessModel)success
                   failure:(ReplyFailure)fail
                  netError:(ReplyError)errorBlock;

#pragma mark -------- 根据自己的需求进行重写,数据转模型  ---------

/**
 之类需要根据自己的需求进行重写
 处理请求成功时,字典转模型的具体实现,并返回字典模型

 @param responseObject 响应数据
 @param requestParams 请求数据
 */
-(id)changeDateForModelWithResponseObject:(id)responseObject requestParams:(NSDictionary *)requestParams;

@end

注意点:

(1)当使用代理方式进行处理网络回调时,需要设置 delegate,调用请求方法

/**
 供子类调用 【  代理方式请求调用方法  】

 @param method 请求方式
 @param params 请求参数数据
 @param isNeedHeader 是否需要 请求头数据
 */
-(void)doRequestWithHttpMethod:(HTTP_REQUEST_METHOD)method
                        params:(id)params
            isNeedHeaderParams:(BOOL)isNeedHeader;

并且实现代理方法即可,后续的处理逻辑可以统一放在代理方法中进行处理

/**
 *  为了降低耦合性,通过这个协议方法可以在对请求状态进行判断
 *
 *  @param type      判断是哪一类发送的请求
 *  @param retStatus 请求成功失败的状态
 */
- (void)DoneBusiness:(enum BusinessHttpType)type status:(ResponseHttpType)retStatus

(2)当使用block回调进行处理网络回调时,只需要调用请求方法,对于每一个请求结果的处理都可以单独进行处理

/**
 供子类调用 【  代理方式请求调用方法  】
 
 @param method 请求方式
 @param params 请求参数数据
 @param isNeedHeader 是否需要 请求头数据
 @param success 成功回调数据模型
 @param fail 失败回调
 @param errorBlock 链接错误回调
 */
-(void)doRequestWithHttpMethod:(HTTP_REQUEST_METHOD)method
                        params:(id)params
        isNeedHeaderParams:(BOOL)isNeedHeader
                   success:(SuccessModel)success
                   failure:(ReplyFailure)fail
                  netError:(ReplyError)errorBlock;

但是不管是用那种方式,如果想要实现字典转模型,那都需要在子类中重写实现具体方法逻辑

/**
 之类需要根据自己的需求进行重写
 处理请求成功时,字典转模型的具体实现,并返回字典模型

 @param responseObject 响应数据
 @param requestParams 请求数据
 */
-(id)changeDateForModelWithResponseObject:(id)responseObject requestParams:(NSDictionary *)requestParams;

两种方式虽然方式不同,但是效果相同,所以只需要根据自己的喜好及业务需求进行选择使用即可。

(4)加载动画HUD展示:

这部分是加载动画hud,具体内容可移步 FrankActivityHUD 动画 进行查看

(5)设备信息加载工具 DeviceManager

这部分主要是为了方便查看、获取一些设备信息而集成的一个工具单例类,功能如下:

#import 
#import 
#import 

//获取当前设备对应的height
#define Screen_height (MAX([[UIScreen mainScreen] bounds].size.height, [[UIScreen mainScreen] bounds].size.width))
//获取当前设备对应的width
#define Screen_width (MIN([[UIScreen mainScreen] bounds].size.height, [[UIScreen mainScreen] bounds].size.width))
//用于判断设备是否为长屏幕iphone,比如iphone5,iphone6,iphone6plus
#define IS_4inchIPHONE ( !IS_IPHONE4 )
//用于判断设备是否为iphone4
#define IS_IPHONE4 ( fabs( ( double )Screen_height - ( double )480 ) < DBL_EPSILON )
//用于判断设备是否为iphone5
#define IS_IPHONE5s_SE ( fabs( ( double )Screen_height - ( double )568 ) < DBL_EPSILON )
//用于判断设备是否为iphone6\iphone6plus
#define IS_IPHONE6_7 ( fabs( ( double )Screen_height - ( double )667 ) < DBL_EPSILON )
//用于判断设备是否为iphone6plus
#define IS_IPHONE6_PLUS ( fabs( ( double )Screen_height - ( double )736 ) < DBL_EPSILON)
//用于判断设备是否为iphone6之后
#define IS_IPHONE6_OR_LATER (((double)Screen_height - (double )568) > DBL_EPSILON)

// 比当前版本大
#define NOT_LESS_THAN_IOSVERSION(version) ([[[UIDevice currentDevice] systemVersion] floatValue] >= version)
// ios7 之后
#define IOS7_OR_LATER ([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending)
// ios8 之后
#define IOS8_OR_LATER ([[[UIDevice currentDevice] systemVersion] compare:@"8.0" options:NSNumericSearch] != NSOrderedAscending)
// ios9 之后
#define IOS9_OR_LATER ([[[UIDevice currentDevice] systemVersion] compare:@"9.0" options:NSNumericSearch] != NSOrderedAscending)
// ios10 之后
#define IOS10_OR_LATER ([[[UIDevice currentDevice] systemVersion] compare:@"10.0" options:NSNumericSearch] != NSOrderedAscending)


@interface DeviceManage : NSObject


/**
 *  网络状态
 */
@property(nonatomic,copy)NSString * netWorkStatus;

/**
 *  设备系统版本
 */
@property (nonatomic, copy) NSString *systemVersion;
/**
 *   设备系统名
 */
@property (nonatomic,  copy) NSString *systemName;
/**
 *  机型
 */
@property (nonatomic,  copy) NSString *deviceModel;
/**
 *  设备名称(别名)
 */
@property (nonatomic,  copy) NSString *deviceName;
/**
 *  设备型号
 */
@property (nonatomic,  copy) NSString *deviceType;
/**
 *  手机总存储容量
 */
@property (nonatomic,  strong)NSString * totalDSB;
/**
 *  手机空闲存储容量
 */
@property (nonatomic,  strong)NSString * freeDSB;
/**
 *  手机总内存容量
 */
@property (nonatomic,  strong)NSString * totalMB;
/**
 *  手机空闲内存容量
 */
@property (nonatomic,  strong)NSString * freeMB;
/**
 *  cpu类型
 */
@property(nonatomic,strong)NSString * cpuType;
/**
 *  屏幕宽度
 */
@property (nonatomic, assign) CGFloat screenWidth;
/**
 *  屏幕高度
 */
@property (nonatomic, assign) CGFloat screenHeight;
/**
 *  分辨率
 */
@property (nonatomic, assign) CGFloat screenScale;
/**
 *  处理器(多核)
 */
@property (nonatomic, assign) NSInteger cpuCoreCount;
/**
 *  应用版本 【version】
 */
@property (nonatomic, strong) NSString *applicationMajorVersion;
/**
 *  最小版本 【build version】
 */
@property (nonatomic, strong) NSString *applicationMinorVersion;
/**
 *  当前应用名
 */
@property (nonatomic, strong) NSString *applicationDisplayName;
/**
 *  应用标识符
 */
@property (nonatomic, strong) NSString *applicationIdentifier;
/**
 *  启动状态
 */
@property (nonatomic, assign) NSInteger fetchLocationErrorCode;//-2--not started or OK, -1--in progress, >=0----failed
/**
 *  获取手机 IP 地址
 */
@property (nonatomic, strong) NSString * phoneIPAdress;
/**
 *   获取手机 Mac 地址
 */
@property (nonatomic, strong) NSString * phoneMacAddress;
/**
 *  获取单例对象
 */
+(DeviceManage *)shareDeviceManage;

@end

(6)数据库存储框架:

文件中包含三个类文件:
(1)FrankFMDBManage:是基于FMDB集成的数据库工具,隔离了SQL语句繁琐的操作,并且结合runtime实现了对象的直接存储操作,支持增、删、改、查、支持原始网络数据的存储
(2)FrankUserDefaults:是对 NSUserDefaults进行的一个简单封装,并且提供了不同类型数据的本地读写功能
(3)NSString+Category:是对NSString的一个分类,将一些常用的NSString功能方法进行封装,以便调用

具体的使用详情可参见 Demo链接: https://github.com/Kinglions/FrankNetworkManage
如有发现存在问题,希望可以及时提出,相互交流,共同进步

你可能感兴趣的:(基于AF的二次封装FrankNetworkManage)