版本记录
版本号 | 时间 |
---|---|
V1.0 | 2018.03.03 |
前言
我们做APP发起网络请求,都离不开一个非常有用的框架AFNetworking,可以说这个框架的知名度已经超过了苹果的底层网络请求部分,很多人可能不知道苹果底层是如何发起网络请求的,但是一定知道
AFNetworking
,接下来几篇我们就一起详细的解析一下这个框架。感兴趣的可以看上面写的几篇。
1. AFNetworking源码探究(一) —— 基本介绍
2. AFNetworking源码探究(二) —— GET请求实现之NSURLSessionDataTask实例化(一)
3. AFNetworking源码探究(三) —— GET请求实现之任务进度设置和通知监听(一)
4. AFNetworking源码探究(四) —— GET请求实现之代理转发思想(一)
5. AFNetworking源码探究(五) —— AFURLSessionManager中NSURLSessionDelegate详细解析(一)
6. AFNetworking源码探究(六) —— AFURLSessionManager中NSURLSessionTaskDelegate详细解析(一)
7. AFNetworking源码探究(七) —— AFURLSessionManager中NSURLSessionDataDelegate详细解析(一)
8. AFNetworking源码探究(八) —— AFURLSessionManager中NSURLSessionDownloadDelegate详细解析(一)
9. AFNetworking源码探究(九) —— AFURLSessionManagerTaskDelegate中三个转发代理方法详细解析(一)
10. AFNetworking源码探究(十) —— 数据解析之数据解析架构的分析(一)
11. AFNetworking源码探究(十一) —— 数据解析之子类中协议方法的实现(二)
12. AFNetworking源码探究(十二) —— 数据解析之子类中协议方法的实现(三)
13. AFNetworking源码探究(十三) —— AFSecurityPolicy与安全认证 (一)
14. AFNetworking源码探究(十四) —— AFSecurityPolicy与安全认证 (二)
15. AFNetworking源码探究(十五) —— 请求序列化之架构分析(一)
16. AFNetworking源码探究(十六) —— 请求序列化之协议方法的实现(二)
17. AFNetworking源码探究(十七) —— _AFURLSessionTaskSwizzling实现方法交换(转载)(一)
回顾
上一篇主要讲述了_AFURLSessionTaskSwizzling
用于方法交换,接下来几篇讲述AFN与UIKit相关的部分。
UIKit相关的类
下面我们看一下UIKit相关的类。
可以看见还是很多关于UIKit的类,都是在原类上的扩展。下面我们就看一下这几个相关的类。
AFNetworkActivityIndicatorManager
这个就是网络请求时候上面旋转的小菊花。
1. 使用
#import "AFNetworkActivityIndicatorManager.h"
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
AFNetworkActivityIndicatorManager
管理状态栏中网络活动指示器的状态。 启用后,它将侦听指示会话任务已启动或完成的通知,并相应地启动或停止对指示器进行动画处理。 活动请求的数量增加和减少很像堆栈或信号量,只要该数量大于零,活动指示器就会动画。
当您的应用程序完成启动时,您应该启用AFNetworkActivityIndicatorManager
的共享实例。 在AppDelegate应用程序中:didFinishLaunchingWithOptions:
你可以用下面的代码来完成:
[[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
通过为sharedManager
设置enabled
为YES
,当请求开始和结束时,网络活动指示器将自动显示并隐藏。 你不需要自己调用incrementActivityCount
或decrementActivityCount
。
2. 指示器的状态
下面看一下指示器的几个状态。
typedef NS_ENUM(NSInteger, AFNetworkActivityManagerState) {
//没有请求
AFNetworkActivityManagerStateNotActive,
//请求延迟开始
AFNetworkActivityManagerStateDelayingStart,
//请求进行中
AFNetworkActivityManagerStateActive,
//请求延迟结束
AFNetworkActivityManagerStateDelayingEnd
};
这里包括四个状态,包括请求、结束、延迟开始和延迟结束。这里可能延迟开始和延迟结束大家需要注意下。如果一个请求时间很短,那么菊花很可能闪一下就结束了。如果很多请求过来,那么菊花会不停的闪啊闪,这显然并不是我们想要的效果。所以设置了这两个状态参数,在一个请求开始的时候,延迟一会在去转菊花,如果在这延迟时间内,请求结束了,那么我就不需要去转菊花了。但是一旦转菊花开始,哪怕很短请求就结束了,我们还是会去转一个时间再去结束,这时间就是延迟结束的时间。
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;
}
//设置状态为没有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;
//结束延迟
self.completionDelay = kDefaultAFNetworkActivityManagerCompletionDelay;
return self;
}
// 延迟时间设置
static NSTimeInterval const kDefaultAFNetworkActivityManagerActivationDelay = 1.0;
static NSTimeInterval const kDefaultAFNetworkActivityManagerCompletionDelay = 0.17;
初始化方法里面有三个通知监听,监听了三个通知,用来监听当前正在进行的网络请求的状态。
下面我们就看这两个通知方法的实现。
//请求开始
- (void)networkRequestDidStart:(NSNotification *)notification {
if ([AFNetworkRequestFromNotification(notification) URL]) {
//增加请求活跃数
[self incrementActivityCount];
}
}
//请求结束
- (void)networkRequestDidFinish:(NSNotification *)notification {
//AFNetworkRequestFromNotification(notification)返回这个通知的request,用来判断request是否是有效的
if ([AFNetworkRequestFromNotification(notification) URL]) {
//减少请求活跃数
[self decrementActivityCount];
}
}
还记得我前面说过的,活动指示器是如何出现的吗?活动请求的数量增加和减少很像堆栈或信号量,只要该数量大于零,活动指示器就会动画。
下面看一下活动指示器活动请求数量的增加还是减少数量的计算。
//请求开始
- (void)networkRequestDidStart:(NSNotification *)notification {
if ([AFNetworkRequestFromNotification(notification) URL]) {
//增加请求活跃数
[self incrementActivityCount];
}
}
//请求结束
- (void)networkRequestDidFinish:(NSNotification *)notification {
//AFNetworkRequestFromNotification(notification)返回这个通知的request,用来判断request是否是有效的
if ([AFNetworkRequestFromNotification(notification) URL]) {
//减少请求活跃数
[self decrementActivityCount];
}
}
//增加请求活跃数
- (void)incrementActivityCount {
//活跃的网络数+1,并手动发送KVO
[self willChangeValueForKey:@"activityCount"];
@synchronized(self) {
_activityCount++;
}
[self didChangeValueForKey:@"activityCount"];
//主线程去做
dispatch_async(dispatch_get_main_queue(), ^{
[self updateCurrentStateForNetworkActivityChange];
});
}
//减少请求活跃数
- (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;
}
}
下面看一个类的核心方法。
// 设置当前小菊花状态
- (void)setCurrentState:(AFNetworkActivityManagerState)currentState {
@synchronized(self) {
if (_currentState != currentState) {
//KVO
[self willChangeValueForKey:@"currentState"];
_currentState = currentState;
switch (currentState) {
//如果为不活跃
case AFNetworkActivityManagerStateNotActive:
//取消两个延迟用的timer
[self cancelActivationDelayTimer];
[self cancelCompletionDelayTimer];
//设置小菊花不可见
[self setNetworkActivityIndicatorVisible:NO];
break;
case AFNetworkActivityManagerStateDelayingStart:
//开启一个定时器延迟去转菊花
[self startActivationDelayTimer];
break;
//如果是活跃状态
case AFNetworkActivityManagerStateActive:
//取消延迟完成的timer
[self cancelCompletionDelayTimer];
//开始转菊花
[self setNetworkActivityIndicatorVisible:YES];
break;
//延迟完成状态
case AFNetworkActivityManagerStateDelayingEnd:
//开启延迟完成timer
[self startCompletionDelayTimer];
break;
}
}
[self didChangeValueForKey:@"currentState"];
}
}
这里重写了状态的setter方法,这里根据当前状态,是否需要开始执行一个延迟开始或者延迟完成,又或者是否需要取消这两个延迟。
后记
本篇主要介绍了
AFNetworkActivityIndicatorManager
这个与UIKit相关的类,后面会继续带着大家看后面的几个类。
网友评论