對于iOS程序猿來說余蟹,AFNetworking
的強大之處卷胯,自然是不用言表,大家都早已深有體會威酒。但是一般在使用這些第三方的時候窑睁,我們一般都會根據(jù)自己的使用習慣及業(yè)務功能需求進行封裝處理挺峡,當然我也一樣,對AFNetworking
進行了二次封裝處理担钮,所以此次發(fā)布出來僅供參考:
<a href="#">注意:使用該框架前橱赠,需要集成 AFNetworking 和 FMDB,因為該框架是基于這兩者進行的二次封裝</a>
<h4>一:框架特點</h4><h6>1:基于AFNetworking
封裝處理箫津,簡化了對AFNetworking
的直接操作狭姨,使調用更加方便簡潔;
2:將AFNetworking
原有的兩種回調方式拓展為了三種回調苏遥,并且支持用戶根據(jù)服務器數(shù)據(jù)格式進行配置饼拍,功能細化,操作簡單田炭;
3:結合FMDB
封裝了數(shù)據(jù)庫师抄,可以根據(jù)需要進行緩存網絡數(shù)據(jù);
4:集成了Delegate
和Block
兩種網絡回調方式教硫,用戶可以根據(jù)自己的喜好進行選擇使用任意一種回調方式叨吮;</h6>
Demo鏈接:https://github.com/Kinglions/FrankNetworkManage</br>
<h4>二:框架解析</h4>
<h6>(1)網絡請求框架:</h6>
/**
* 網絡請求封裝
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <AFNetworking.h>
#import <AFNetworking/AFURLSessionManager.h>
#import "FrankNetworkMacro.h"
typedef void (^RequestPrepare)();
typedef void (^RequestFinally)();
/**
請求成功回調
@param task 請求對象
@param responseObject 響應數(shù)據(jù)
@param requestParams 請求參數(shù)
*/
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 <AFMultipartFormData> formData);
/**
基礎網絡請求 其他的請求統(tǒng)一由此類發(fā)出
- 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: 進行緩存栋豫,并且請求數(shù)據(jù)時先進行加載緩存挤安,本次請求數(shù)據(jù),下次加載
*/
typedef NS_ENUM(NSUInteger, NetworkCacheType) {
NetworkCacheType_Never = 0,
NetworkCacheType_OnlyCache,
NetworkCacheType_CacheAndLoad,
};
@interface FrankNetworkManage : NSObject
/**
* 創(chuàng)建單例對象
*/
+(instancetype)shareManager;
/**
網絡數(shù)據(jù)的緩存處理類型
*/
@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;
/**
共外界調用配置 判斷邏輯【根據(jù)服務器返回值進行配置,可以在 Appdelegate 中進行設置】
*
* @return YES 表示數(shù)據(jù)正確丛肢,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;
/**
* 統(tǒng)一網絡請求
*
* @param method 請求類型(直接調用 枚舉)
* @param urlString 請求URLString
* @param headerParams 請求頭添加的參數(shù)
* @param params 請求參數(shù)
* @param finally 請求結束,進行清理(直接調用)
* @param sucess 請求成功杠步,數(shù)據(jù)正常
* @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 與指定的圖片相關聯(lián)的名稱诚些,這是由后端寫接口的人指定的,如imagefiles
* @param mimeType 默認為image/jpeg
* @param parameters 參數(shù)
* @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)
屬性皇型,這個是根據(jù)后臺的數(shù)據(jù)格式配置請求結果判斷的回調诬烹,只需要在AppDelegate
中進行配置一次就行砸烦。例如:
<h6>(2)網絡下載框架:</h6>
#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;
/**
下載狀態(tài)
- DownloadStatus_SuspendDown: 暫停下載
- DownloadStatus_ResumingDown: 開始下載
*/
-(void)setDownloadStatus:(DownloadStatus)status;
@end
<h6>(3)請求類BaseModel類 :</h6>
這個類是為了方便使用,而創(chuàng)建的一個基類框架绞吁,相當于在ViewController
和FrankNetworkManage
中間添加的一層幢痘,用于處理數(shù)據(jù)交互相關邏輯,所以后期創(chuàng)建具體請求類只需要集成該BaseRequestHttpModel
類掀泳,重寫父類方法即可雪隧。
代碼解析:
#import <Foundation/Foundation.h>
#import "FrankNetworkMacro.h"
/**
請求成功時返回的數(shù)據(jù)
@param models 數(shù)據(jù)模型
*/
typedef void(^SuccessModel)(id models);
/**
代理方式下的 網絡請求結果狀態(tài)
- ResponseHttpType_Success: 請求成功
- ResponseHttpType_Failure: 請求失敗
- ResponseHttpType_NetworkError: 網絡異常
*/
typedef NS_ENUM(NSInteger,ResponseHttpType) {
ResponseHttpType_Success,
ResponseHttpType_Failure,
ResponseHttpType_NetworkError,
};
/**
代理方式下的 網絡請求類型,枚舉回調區(qū)分
*/
typedef NS_ENUM(NSInteger,BusinessHttpType) {
BusinessHttpType_None = 0,// 默認狀態(tài)
BusinessHttpType_LoadWeather ,// 請求天氣
// 此處可以根據(jù)自己的工程需求進行添加枚舉分類员舵。脑沿。。
};
#pragma mark -------- 通過 代理 方式處理請求回調马僻,當使用 block 方式處理時庄拇,可以忽略代理 ---------
@protocol BaseRequestHttpModelDelegate <NSObject>
@optional
/**
* 為了降低耦合性,通過這個協(xié)議方法可以在對請求狀態(tài)進行判斷
*
* @param type 判斷是哪一類發(fā)送的請求
* @param retStatus 請求成功失敗的狀態(tài)
*/
- (void)DoneBusiness:(enum BusinessHttpType)type status:(ResponseHttpType)retStatus;
@end
@interface BaseRequestHttpModel : NSObject
/**
請求地址
*/
@property (nonatomic,strong)NSString * urlStr;
/**
請求頭數(shù)據(jù)字典
*/
@property (nonatomic,strong)NSMutableDictionary * headerParams;
/**
網絡請求失敗回調
*/
@property (nonatomic,copy)ReplyFailure failureBlock;
/**
網絡錯誤回調
*/
@property (nonatomic,copy)ReplyError networkerrBlock;
#pragma mark -------- 通過 代理 方式處理請求回調 ---------
#pragma mark -------- 通過 代理 方式處理請求回調 ---------
/**
設置網絡請求代理【當使用 block 方式處理時韭邓,可以忽略代理】
*/
@property (nonatomic,weak)id <BaseRequestHttpModelDelegate>delegate;
/**
網絡請求API類型
*/
@property (nonatomic,assign) BusinessHttpType businessType;
/**
告知當前網絡處理狀態(tài)
*/
-(void)doneBusiness:(ResponseHttpType)returnStatus;
/**
供子類調用 【 代理方式請求調用方法 】
@param method 請求方式
@param params 請求參數(shù)數(shù)據(jù)
@param isNeedHeader 是否需要 請求頭數(shù)據(jù)
*/
-(void)doRequestWithHttpMethod:(HTTP_REQUEST_METHOD)method
params:(id)params
isNeedHeaderParams:(BOOL)isNeedHeader;
#pragma mark -------- 通過 block 方式處理請求回調 ---------
#pragma mark -------- 通過 block 方式處理請求回調 ---------
/**
供子類調用 【 代理方式請求調用方法 】
@param method 請求方式
@param params 請求參數(shù)數(shù)據(jù)
@param isNeedHeader 是否需要 請求頭數(shù)據(jù)
@param success 成功回調數(shù)據(jù)模型
@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 -------- 根據(jù)自己的需求進行重寫泛鸟,數(shù)據(jù)轉模型 ---------
/**
之類需要根據(jù)自己的需求進行重寫
處理請求成功時批幌,字典轉模型的具體實現(xiàn)绽榛,并返回字典模型
@param responseObject 響應數(shù)據(jù)
@param requestParams 請求數(shù)據(jù)
*/
-(id)changeDateForModelWithResponseObject:(id)responseObject requestParams:(NSDictionary *)requestParams;
@end
<h6>注意點:</h6>
(1)當使用代理方式進行處理網絡回調時氮趋,需要設置 delegate
,調用請求方法
/**
供子類調用 【 代理方式請求調用方法 】
@param method 請求方式
@param params 請求參數(shù)數(shù)據(jù)
@param isNeedHeader 是否需要 請求頭數(shù)據(jù)
*/
-(void)doRequestWithHttpMethod:(HTTP_REQUEST_METHOD)method
params:(id)params
isNeedHeaderParams:(BOOL)isNeedHeader;
并且實現(xiàn)代理方法即可鸭你,后續(xù)的處理邏輯可以統(tǒng)一放在代理方法中進行處理
/**
* 為了降低耦合性屈张,通過這個協(xié)議方法可以在對請求狀態(tài)進行判斷
*
* @param type 判斷是哪一類發(fā)送的請求
* @param retStatus 請求成功失敗的狀態(tài)
*/
- (void)DoneBusiness:(enum BusinessHttpType)type status:(ResponseHttpType)retStatus
(2)當使用block
回調進行處理網絡回調時,只需要調用請求方法袱巨,對于每一個請求結果的處理都可以單獨進行處理
/**
供子類調用 【 代理方式請求調用方法 】
@param method 請求方式
@param params 請求參數(shù)數(shù)據(jù)
@param isNeedHeader 是否需要 請求頭數(shù)據(jù)
@param success 成功回調數(shù)據(jù)模型
@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;
但是不管是用那種方式阁谆,如果想要實現(xiàn)字典轉模型,那都需要在子類中重寫實現(xiàn)具體方法邏輯
/**
之類需要根據(jù)自己的需求進行重寫
處理請求成功時愉老,字典轉模型的具體實現(xiàn)场绿,并返回字典模型
@param responseObject 響應數(shù)據(jù)
@param requestParams 請求數(shù)據(jù)
*/
-(id)changeDateForModelWithResponseObject:(id)responseObject requestParams:(NSDictionary *)requestParams;
兩種方式雖然方式不同,但是效果相同嫉入,所以只需要根據(jù)自己的喜好及業(yè)務需求進行選擇使用即可焰盗。
<h6>(4)加載動畫HUD展示:</h6>
這部分是加載動畫hud,具體內容可移步 FrankActivityHUD 動畫 進行查看</br>
<h6>(5)設備信息加載工具 DeviceManager
:</h6>
這部分主要是為了方便查看咒林、獲取一些設備信息而集成的一個工具單例類姨谷,功能如下:
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <UIKit/UIKit.h>
//獲取當前設備對應的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
/**
* 網絡狀態(tài)
*/
@property(nonatomic,copy)NSString * netWorkStatus;
/**
* 設備系統(tǒng)版本
*/
@property (nonatomic, copy) NSString *systemVersion;
/**
* 設備系統(tǒng)名
*/
@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;
/**
* 啟動狀態(tài)
*/
@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
<h6>(6)數(shù)據(jù)庫存儲框架:</h6>
文件中包含三個類文件:
(1)FrankFMDBManage:
是基于FMDB
集成的數(shù)據(jù)庫工具瞎颗,隔離了SQL語句
繁瑣的操作件甥,并且結合runtime
實現(xiàn)了對象的直接存儲操作捌议,支持增、刪引有、改瓣颅、查、支持原始網絡數(shù)據(jù)的存儲
(2)FrankUserDefaults:
是對 NSUserDefaults
進行的一個簡單封裝譬正,并且提供了不同類型數(shù)據(jù)的本地讀寫功能
(3)NSString+Category:
是對NSString
的一個分類宫补,將一些常用的NSString
功能方法進行封裝,以便調用
具體的使用詳情可參見 Demo鏈接: https://github.com/Kinglions/FrankNetworkManage</br> 如有發(fā)現(xiàn)存在問題曾我,希望可以及時提出粉怕,相互交流,共同進步