版本記錄
版本號(hào) | 時(shí)間 |
---|---|
V1.0 | 2018.03.03 |
前言
我們做APP發(fā)起網(wǎng)絡(luò)請(qǐng)求趣些,都離不開一個(gè)非常有用的框架AFNetworking,可以說這個(gè)框架的知名度已經(jīng)超過了蘋果的底層網(wǎng)絡(luò)請(qǐng)求部分深碱,很多人可能不知道蘋果底層是如何發(fā)起網(wǎng)絡(luò)請(qǐng)求的芍锚,但是一定知道
AFNetworking
,接下來幾篇我們就一起詳細(xì)的解析一下這個(gè)框架扁瓢。感興趣的可以看上面寫的幾篇。
1. AFNetworking源碼探究(一) —— 基本介紹
2. AFNetworking源碼探究(二) —— GET請(qǐng)求實(shí)現(xiàn)之NSURLSessionDataTask實(shí)例化(一)
3. AFNetworking源碼探究(三) —— GET請(qǐng)求實(shí)現(xiàn)之任務(wù)進(jìn)度設(shè)置和通知監(jiān)聽(一)
4. AFNetworking源碼探究(四) —— GET請(qǐng)求實(shí)現(xiàn)之代理轉(zhuǎn)發(fā)思想(一)
5. AFNetworking源碼探究(五) —— AFURLSessionManager中NSURLSessionDelegate詳細(xì)解析(一)
6. AFNetworking源碼探究(六) —— AFURLSessionManager中NSURLSessionTaskDelegate詳細(xì)解析(一)
7. AFNetworking源碼探究(七) —— AFURLSessionManager中NSURLSessionDataDelegate詳細(xì)解析(一)
8. AFNetworking源碼探究(八) —— AFURLSessionManager中NSURLSessionDownloadDelegate詳細(xì)解析(一)
9. AFNetworking源碼探究(九) —— AFURLSessionManagerTaskDelegate中三個(gè)轉(zhuǎn)發(fā)代理方法詳細(xì)解析(一)
10. AFNetworking源碼探究(十) —— 數(shù)據(jù)解析之?dāng)?shù)據(jù)解析架構(gòu)的分析(一)
11. AFNetworking源碼探究(十一) —— 數(shù)據(jù)解析之子類中協(xié)議方法的實(shí)現(xiàn)(二)
12. AFNetworking源碼探究(十二) —— 數(shù)據(jù)解析之子類中協(xié)議方法的實(shí)現(xiàn)(三)
13. AFNetworking源碼探究(十三) —— AFSecurityPolicy與安全認(rèn)證 (一)
14. AFNetworking源碼探究(十四) —— AFSecurityPolicy與安全認(rèn)證 (二)
15. AFNetworking源碼探究(十五) —— 請(qǐng)求序列化之架構(gòu)分析(一)
16. AFNetworking源碼探究(十六) —— 請(qǐng)求序列化之協(xié)議方法的實(shí)現(xiàn)(二)
17. AFNetworking源碼探究(十七) —— _AFURLSessionTaskSwizzling實(shí)現(xiàn)方法交換(轉(zhuǎn)載)(一)
回顧
上一篇主要講述了_AFURLSessionTaskSwizzling
用于方法交換补君,接下來幾篇講述AFN與UIKit相關(guān)的部分引几。
UIKit相關(guān)的類
下面我們看一下UIKit相關(guān)的類。
可以看見還是很多關(guān)于UIKit的類,都是在原類上的擴(kuò)展伟桅。下面我們就看一下這幾個(gè)相關(guān)的類敞掘。
AFNetworkActivityIndicatorManager
這個(gè)就是網(wǎng)絡(luò)請(qǐng)求時(shí)候上面旋轉(zhuǎn)的小菊花。
1. 使用
#import "AFNetworkActivityIndicatorManager.h"
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
AFNetworkActivityIndicatorManager
管理狀態(tài)欄中網(wǎng)絡(luò)活動(dòng)指示器的狀態(tài)楣铁。 啟用后玖雁,它將偵聽指示會(huì)話任務(wù)已啟動(dòng)或完成的通知,并相應(yīng)地啟動(dòng)或停止對(duì)指示器進(jìn)行動(dòng)畫處理盖腕。 活動(dòng)請(qǐng)求的數(shù)量增加和減少很像堆椇斩或信號(hào)量,只要該數(shù)量大于零溃列,活動(dòng)指示器就會(huì)動(dòng)畫劲厌。
當(dāng)您的應(yīng)用程序完成啟動(dòng)時(shí),您應(yīng)該啟用AFNetworkActivityIndicatorManager
的共享實(shí)例听隐。 在AppDelegate應(yīng)用程序中:didFinishLaunchingWithOptions:
你可以用下面的代碼來完成:
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
通過為sharedManager
設(shè)置enabled
為YES
补鼻,當(dāng)請(qǐng)求開始和結(jié)束時(shí),網(wǎng)絡(luò)活動(dòng)指示器將自動(dòng)顯示并隱藏雅任。 你不需要自己調(diào)用incrementActivityCount
或decrementActivityCount
风范。
2. 指示器的狀態(tài)
下面看一下指示器的幾個(gè)狀態(tài)。
typedef NS_ENUM(NSInteger, AFNetworkActivityManagerState) {
//沒有請(qǐng)求
AFNetworkActivityManagerStateNotActive,
//請(qǐng)求延遲開始
AFNetworkActivityManagerStateDelayingStart,
//請(qǐng)求進(jìn)行中
AFNetworkActivityManagerStateActive,
//請(qǐng)求延遲結(jié)束
AFNetworkActivityManagerStateDelayingEnd
};
這里包括四個(gè)狀態(tài)沪么,包括請(qǐng)求硼婿、結(jié)束、延遲開始和延遲結(jié)束成玫。這里可能延遲開始和延遲結(jié)束大家需要注意下加酵。如果一個(gè)請(qǐng)求時(shí)間很短,那么菊花很可能閃一下就結(jié)束了哭当。如果很多請(qǐng)求過來猪腕,那么菊花會(huì)不停的閃啊閃,這顯然并不是我們想要的效果钦勘。所以設(shè)置了這兩個(gè)狀態(tài)參數(shù)陋葡,在一個(gè)請(qǐng)求開始的時(shí)候,延遲一會(huì)在去轉(zhuǎn)菊花彻采,如果在這延遲時(shí)間內(nèi)腐缤,請(qǐng)求結(jié)束了,那么我就不需要去轉(zhuǎn)菊花了肛响。但是一旦轉(zhuǎn)菊花開始岭粤,哪怕很短請(qǐng)求就結(jié)束了,我們還是會(huì)去轉(zhuǎn)一個(gè)時(shí)間再去結(jié)束特笋,這時(shí)間就是延遲結(jié)束的時(shí)間剃浇。
3. 初始化方法
下面看一下初始化方法。
+ (instancetype)sharedManager {
static AFNetworkActivityIndicatorManager *_sharedManager = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_sharedManager = [[self alloc] init];
});
return _sharedManager;
}
- (instancetype)init {
self = [super init];
if (!self) {
return nil;
}
//設(shè)置狀態(tài)為沒有request活躍
self.currentState = AFNetworkActivityManagerStateNotActive;
//開始下載通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidStart:) name:AFNetworkingTaskDidResumeNotification object:nil];
//掛起通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidFinish:) name:AFNetworkingTaskDidSuspendNotification object:nil];
//完成通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidFinish:) name:AFNetworkingTaskDidCompleteNotification object:nil];
//開始延遲
self.activationDelay = kDefaultAFNetworkActivityManagerActivationDelay;
//結(jié)束延遲
self.completionDelay = kDefaultAFNetworkActivityManagerCompletionDelay;
return self;
}
// 延遲時(shí)間設(shè)置
static NSTimeInterval const kDefaultAFNetworkActivityManagerActivationDelay = 1.0;
static NSTimeInterval const kDefaultAFNetworkActivityManagerCompletionDelay = 0.17;
初始化方法里面有三個(gè)通知監(jiān)聽,監(jiān)聽了三個(gè)通知虎囚,用來監(jiān)聽當(dāng)前正在進(jìn)行的網(wǎng)絡(luò)請(qǐng)求的狀態(tài)角塑。
下面我們就看這兩個(gè)通知方法的實(shí)現(xiàn)。
//請(qǐng)求開始
- (void)networkRequestDidStart:(NSNotification *)notification {
if ([AFNetworkRequestFromNotification(notification) URL]) {
//增加請(qǐng)求活躍數(shù)
[self incrementActivityCount];
}
}
//請(qǐng)求結(jié)束
- (void)networkRequestDidFinish:(NSNotification *)notification {
//AFNetworkRequestFromNotification(notification)返回這個(gè)通知的request,用來判斷request是否是有效的
if ([AFNetworkRequestFromNotification(notification) URL]) {
//減少請(qǐng)求活躍數(shù)
[self decrementActivityCount];
}
}
還記得我前面說過的淘讥,活動(dòng)指示器是如何出現(xiàn)的嗎圃伶?活動(dòng)請(qǐng)求的數(shù)量增加和減少很像堆棧或信號(hào)量蒲列,只要該數(shù)量大于零窒朋,活動(dòng)指示器就會(huì)動(dòng)畫。
下面看一下活動(dòng)指示器活動(dòng)請(qǐng)求數(shù)量的增加還是減少數(shù)量的計(jì)算蝗岖。
//請(qǐng)求開始
- (void)networkRequestDidStart:(NSNotification *)notification {
if ([AFNetworkRequestFromNotification(notification) URL]) {
//增加請(qǐng)求活躍數(shù)
[self incrementActivityCount];
}
}
//請(qǐng)求結(jié)束
- (void)networkRequestDidFinish:(NSNotification *)notification {
//AFNetworkRequestFromNotification(notification)返回這個(gè)通知的request,用來判斷request是否是有效的
if ([AFNetworkRequestFromNotification(notification) URL]) {
//減少請(qǐng)求活躍數(shù)
[self decrementActivityCount];
}
}
//增加請(qǐng)求活躍數(shù)
- (void)incrementActivityCount {
//活躍的網(wǎng)絡(luò)數(shù)+1炼邀,并手動(dòng)發(fā)送KVO
[self willChangeValueForKey:@"activityCount"];
@synchronized(self) {
_activityCount++;
}
[self didChangeValueForKey:@"activityCount"];
//主線程去做
dispatch_async(dispatch_get_main_queue(), ^{
[self updateCurrentStateForNetworkActivityChange];
});
}
//減少請(qǐng)求活躍數(shù)
- (void)decrementActivityCount {
[self willChangeValueForKey:@"activityCount"];
@synchronized(self) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu"
_activityCount = MAX(_activityCount - 1, 0);
#pragma clang diagnostic pop
}
[self didChangeValueForKey:@"activityCount"];
dispatch_async(dispatch_get_main_queue(), ^{
[self updateCurrentStateForNetworkActivityChange];
});
}
后面需要用下面的方法判斷是否是活躍的
//判斷是否活躍
- (BOOL)isNetworkActivityOccurring {
@synchronized(self) {
return self.activityCount > 0;
}
}
下面看一個(gè)類的核心方法。
// 設(shè)置當(dāng)前小菊花狀態(tài)
- (void)setCurrentState:(AFNetworkActivityManagerState)currentState {
@synchronized(self) {
if (_currentState != currentState) {
//KVO
[self willChangeValueForKey:@"currentState"];
_currentState = currentState;
switch (currentState) {
//如果為不活躍
case AFNetworkActivityManagerStateNotActive:
//取消兩個(gè)延遲用的timer
[self cancelActivationDelayTimer];
[self cancelCompletionDelayTimer];
//設(shè)置小菊花不可見
[self setNetworkActivityIndicatorVisible:NO];
break;
case AFNetworkActivityManagerStateDelayingStart:
//開啟一個(gè)定時(shí)器延遲去轉(zhuǎn)菊花
[self startActivationDelayTimer];
break;
//如果是活躍狀態(tài)
case AFNetworkActivityManagerStateActive:
//取消延遲完成的timer
[self cancelCompletionDelayTimer];
//開始轉(zhuǎn)菊花
[self setNetworkActivityIndicatorVisible:YES];
break;
//延遲完成狀態(tài)
case AFNetworkActivityManagerStateDelayingEnd:
//開啟延遲完成timer
[self startCompletionDelayTimer];
break;
}
}
[self didChangeValueForKey:@"currentState"];
}
}
這里重寫了狀態(tài)的setter方法剪侮,這里根據(jù)當(dāng)前狀態(tài),是否需要開始執(zhí)行一個(gè)延遲開始或者延遲完成洛退,又或者是否需要取消這兩個(gè)延遲瓣俯。
后記
本篇主要介紹了
AFNetworkActivityIndicatorManager
這個(gè)與UIKit相關(guān)的類,后面會(huì)繼續(xù)帶著大家看后面的幾個(gè)類兵怯。