如題:本篇是對(duì)于HYBNetworking的閱讀學(xué)習(xí)筆記
HYBNetworking是基于AFN 的二次封裝,
1.實(shí)現(xiàn)了 POST,GET, 上傳圖片,上傳文件,下載文件功能.
2.提供了數(shù)據(jù)緩存的簡(jiǎn)單策略
3.可以設(shè)置 baseURL,最大并發(fā)數(shù),過(guò)期時(shí)間,
特點(diǎn):基于 OC, 使用類方法請(qǐng)求.基礎(chǔ),入門級(jí).
同樣的BaseUrl 用一個(gè) manager
//MARK:BaseUrl
/*
* 用于指定網(wǎng)絡(luò)請(qǐng)求接口的基礎(chǔ)url,如:
* 通常在AppDelegate中啟動(dòng)時(shí)就設(shè)置一次就可以了。
+ (void)updateBaseUrl:(NSString *)baseUrl;
+ (NSString *)baseUrl;
sg_privateNetworkBaseUrl
static NSString *sg_privateNetworkBaseUrl = nil;
-> 接收baseUrl
sg_isBaseURLChanged
static BOOL sg_isBaseURLChanged = YES;
->記錄 baseUrl 是否改變,
發(fā)生改變?cè)?+ (AFHTTPSessionManager *)manager 方法中會(huì)重新生成并設(shè)置一個(gè)新個(gè) session ,
未發(fā)生改變就使用之前的 session
*/
+ (void)updateBaseUrl:(NSString *)baseUrl {
if (![baseUrl isEqualToString:sg_privateNetworkBaseUrl] && baseUrl && baseUrl.length) {
sg_isBaseURLChanged = YES;
} else {
sg_isBaseURLChanged = NO;
}
sg_privateNetworkBaseUrl = baseUrl;
}
+ (NSString *)baseUrl {
return sg_privateNetworkBaseUrl;
}
//MARK:timeout
/**
* 設(shè)置請(qǐng)求超時(shí)時(shí)間惯驼,默認(rèn)為60秒
* @param timeout 超時(shí)時(shí)間
static NSTimeInterval sg_timeout = 60.0f;
*在實(shí)例化 manager 方法中設(shè)置 這應(yīng)該會(huì)導(dǎo)致一個(gè)問(wèn)題 在同一個(gè) baseURL下 更換 timeout是無(wú)效的,因?yàn)?manager 是同一個(gè),而timeout也只是在實(shí)例化 manager時(shí)設(shè)置了一次.當(dāng)然這個(gè)屬性也大概設(shè)置一次也就夠了吧
manager.requestSerializer.timeoutInterval = sg_timeout;
*/
+ (void)setTimeout:(NSTimeInterval)timeout;
關(guān)于網(wǎng)絡(luò)可達(dá)性
關(guān)于可達(dá)性監(jiān)測(cè),在 apple官網(wǎng)有示例代碼:https://developer.apple.com/library/content/samplecode/Reachability/Introduction/Intro.html
//MARK:shouldObtain
/**
* 當(dāng)檢查到網(wǎng)絡(luò)異常時(shí)愚铡,是否從從本地提取數(shù)據(jù)。默認(rèn)為NO精堕。一旦設(shè)置為YES,當(dāng)設(shè)置刷新緩存時(shí)丰歌,
* 若網(wǎng)絡(luò)異常也會(huì)從緩存中讀取數(shù)據(jù)。同樣予跌,如果設(shè)置超時(shí)不回調(diào),同樣也會(huì)在網(wǎng)絡(luò)異常時(shí)回調(diào)善茎,除非
* 本地沒有數(shù)據(jù)券册!
*
*/
+ (void)obtainDataFromLocalWhenNetworkUnconnected:(BOOL)shouldObtain;
/**
* 在設(shè)置改屬性的時(shí)候會(huì)進(jìn)行一次可達(dá)性的測(cè)試 獲取到網(wǎng)絡(luò)狀態(tài)
* 可達(dá)性測(cè)試也只是在設(shè)置 shouldObtain 屬性時(shí)進(jìn)行了一次檢查,這.應(yīng)該.有問(wèn)題.比如在檢測(cè)的時(shí)候是 wifi 狀態(tài),在我請(qǐng)求的時(shí)候沒有網(wǎng)絡(luò).那.怎么辦,如果每次請(qǐng)求前都做一次可達(dá)性檢查,性能會(huì)不會(huì)有影響
* HYB中使用方法如下:
*/
typedef NS_ENUM(NSInteger, HYBNetworkStatus) {
kHYBNetworkStatusUnknown = -1,//未知網(wǎng)絡(luò)
kHYBNetworkStatusNotReachable = 0,//網(wǎng)絡(luò)無(wú)連接
kHYBNetworkStatusReachableViaWWAN = 1,//2,3垂涯,4G網(wǎng)絡(luò)
kHYBNetworkStatusReachableViaWiFi = 2,//WIFI網(wǎng)絡(luò)
};
+ (void)detectNetwork {
AFNetworkReachabilityManager *reachabilityManager = [AFNetworkReachabilityManager sharedManager];
[reachabilityManager startMonitoring];
[reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
if (status == AFNetworkReachabilityStatusNotReachable){
sg_networkStatus = kHYBNetworkStatusNotReachable;
} else if (status == AFNetworkReachabilityStatusUnknown){
sg_networkStatus = kHYBNetworkStatusUnknown;
} else if (status == AFNetworkReachabilityStatusReachableViaWWAN){
sg_networkStatus = kHYBNetworkStatusReachableViaWWAN;
} else if (status == AFNetworkReachabilityStatusReachableViaWiFi){
sg_networkStatus = kHYBNetworkStatusReachableViaWiFi;
}
}];
}
在網(wǎng)絡(luò)不可達(dá)是是否緩存數(shù)據(jù)
//MARK:sg_cacheGet && sg_cachePost
/**
*
* 默認(rèn)只緩存GET請(qǐng)求的數(shù)據(jù)烁焙,對(duì)于POST請(qǐng)求是不緩存的。如果要緩存POST獲取的數(shù)據(jù)耕赘,需要手動(dòng)調(diào)用設(shè)置
* 對(duì)JSON類型數(shù)據(jù)有效骄蝇,對(duì)于PLIST、XML不確定操骡!
* @param isCacheGet
* @param shouldCachePost 默認(rèn)為NO
對(duì)應(yīng):
static BOOL sg_cacheGet = YES;
static BOOL sg_cachePost = NO;
sg_cacheGet,sg_cachePost
會(huì)在進(jìn)行網(wǎng)絡(luò)請(qǐng)求之前使用,判斷其值和 HYBNetworkStatus 決定是發(fā)起請(qǐng)求 還是提取本地緩存數(shù)據(jù)
會(huì)在網(wǎng)絡(luò)請(qǐng)求成功之后使用,決定是否緩存數(shù)據(jù)到本地
*/
+ (void)cacheGetRequest:(BOOL)isCacheGet shoulCachePost:(BOOL)shouldCachePost;
配置請(qǐng)求格式
//MARK:配置請(qǐng)求格式
/*
* 配置請(qǐng)求格式九火,默認(rèn)為JSON。如果要求傳XML或者PLIST册招,請(qǐng)?jiān)谌峙渲靡幌? * @param requestType 請(qǐng)求格式岔激,默認(rèn)為JSON
* @param responseType 響應(yīng)格式,默認(rèn)為JSO是掰,
* @param shouldAutoEncode YES or NO,默認(rèn)為NO虑鼎,是否自動(dòng)encode url
* @param shouldCallbackOnCancelRequest 當(dāng)取消請(qǐng)求時(shí),是否要回調(diào)键痛,默認(rèn)為YES
*/
+ (void)configRequestType:(HYBRequestType)requestType
responseType:(HYBResponseType)responseType
shouldAutoEncodeUrl:(BOOL)shouldAutoEncode
callbackOnCancelRequest:(BOOL)shouldCallbackOnCancelRequest;
取消請(qǐng)求
在每次發(fā)起請(qǐng)求后吧 session 方法添加到一個(gè)數(shù)組中,已方便取消等操作
//MARK:取消請(qǐng)求
/**
* 根據(jù) url 請(qǐng)求事實(shí)上只是在遍歷 allTasks 找到 [task.currentRequest.URL.absoluteString hasSuffix:url]
[task cancel] 后移除 allTasks
*/
+ (void)cancelAllRequest;
+ (void)cancelRequestWithURL:(NSString *)url;
POST && GET請(qǐng)求
HYB 提供了3個(gè) GET 方法,2個(gè) POST 方法,但是最終都會(huì)調(diào)用同一個(gè)"全能函數(shù)"
_requestWithUrl:refreshCache: httpMedth: params: progress: success: fail:
//MARK:POST && GET
/*!
* GET 已全參數(shù)的為例子
*/
+ (HYBURLSessionTask *)getWithUrl:(NSString *)url
refreshCache:(BOOL)refreshCache
params:(NSDictionary *)params
progress:(HYBGetProgress)progress
success:(HYBResponseSuccess)success
fail:(HYBResponseFail)fail;
/**
* POST 已全參數(shù)的為例子
*/
+ (HYBURLSessionTask *)postWithUrl:(NSString *)url
refreshCache:(BOOL)refreshCache
params:(NSDictionary *)params
progress:(HYBPostProgress)progress
success:(HYBResponseSuccess)success
fail:(HYBResponseFail)fail;
/**
* POST 和 GET 最終都是調(diào)用同一個(gè)方法 如下 httpMedth 1:get 2:post
* 此方法是核心方法,以上都是為這個(gè)方法提供支持 本方法 212行
*/
+ (HYBURLSessionTask *)_requestWithUrl:(NSString *)url
refreshCache:(BOOL)refreshCache
httpMedth:(NSUInteger)httpMethod
params:(NSDictionary *)params
progress:(HYBDownloadProgress)progress
success:(HYBResponseSuccess)success
fail:(HYBResponseFail)fail {
/** 此方法中做了幾件事
1.處理 url 根據(jù)
1)是否有 baseURL 2) 是否需要 encode (在請(qǐng)求頭設(shè)置)
2.實(shí)例化 manager
3.判斷 httpMethod 決定 POST 還是 GET
4.判斷能否鏈接網(wǎng)絡(luò), sg_cacheGet && sg_cachePost 是否 需要從本地緩存中提取數(shù)據(jù)
5.將 sessin 放到數(shù)組中 [[self allTasks] addObject:session]; 1.用戶取消請(qǐng)求 2.可以用于判斷某個(gè)請(qǐng)求是否在進(jìn)行中(HYB 中沒有體現(xiàn))
NSURLSessionDataTask session task
6.在成功或者失敗的回調(diào)中調(diào)用 success fail 并將 session 從 [self allTasks] 中移除
7.根據(jù) sg_cacheGet && sg_cachePost 判斷是否需要進(jìn)行本地緩存數(shù)據(jù)
*/
}
/**
* 上傳圖片 上傳文件 下載文件 與以上相去不遠(yuǎn)
*/
關(guān)于緩存
/**
* MARK: 緩存到本地
*/
//緩存路徑
static inline NSString *cachePath() {
return [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/HYBNetworkingCaches"];
}
//MD5
+ (NSString *)hybnetworking_md5:(NSString *)string {
if (string == nil || [string length] == 0) {
return nil;
}
unsigned char digest[CC_MD5_DIGEST_LENGTH], i;
CC_MD5([string UTF8String], (int)[string lengthOfBytesUsingEncoding:NSUTF8StringEncoding], digest);
NSMutableString *ms = [NSMutableString string];
for (i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
[ms appendFormat:@"%02x", (int)(digest[i])];
}
return [ms copy];
}
+ (void)cacheResponseObject:(id)responseObject request:(NSURLRequest *)request parameters:params {
/**
*1.判斷路徑下有沒有文件夾 沒有就搞一個(gè)
*2.url + param 進(jìn)行 拼接字符串后 MD5加密 做key (緩存 data 名 拼接在路徑上)
*
*/
//核心
[[NSFileManager defaultManager] createFileAtPath:path contents:data attributes:nil]
}
/**
* MARK: 獲取緩存
*/
+ (id)cahceResponseWithURL:(NSString *)url parameters:params {
id cacheData = nil;
/**
* 拼接路徑
* 去除緩存內(nèi)容
*/
NSData *data = [[NSFileManager defaultManager] contentsAtPath:path];
return cacheData;
}
//獲取緩存總量
+ (unsigned long long)totalCacheSize;
//設(shè)置自動(dòng)清理緩存的上線
+ (void)autoToClearCacheWithLimitedToSize:(NSUInteger)mSize;
//清除緩存
+ (void)clearCaches;
//設(shè)置是否是 debug 模式
+ (void)enableInterfaceDebug:(BOOL)isDebug;
//MARK:LOG
#ifdef DEBUG
#define NLog(s, ... ) NSLog( @"[%@ in line %d] ===============>%@", [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#else
#define NLog(s, ... )
#endif