这个模块主要包括下面两个类
AFURLSessionManager
AFHTTPSessionManager
AFHTTPSessionManager继承自AFURLSessionManager,通常我们使用AFNetworking时,会像下面这样
NSString *urlStr = @"https://api.douban.com/v2/movie/top250";
NSDictionary *dic = @{@"start":@(1),
@"count":@(5)
};
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// manager.requestSerializer.timeoutInterval = 5;
[manager GET:urlStr parameters:dic progress:^(NSProgress * _Nonnull downloadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"success");
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}];
这一段代码AFN内部做了什么呢?
初始化
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
这一行代码主要是做了初始化的操作,源码如下
- (instancetype)initWithBaseURL:(NSURL *)url
sessionConfiguration:(NSURLSessionConfiguration *)configuration
{
// 1、调用父类(AFURLSessionManager)初始化方法
self = [super initWithSessionConfiguration:configuration];
if (!self) {
return nil;
}
// Ensure terminal slash for baseURL path, so that NSURL +URLWithString:relativeToURL: works as expected
// 2、url有值且没有‘/’,那么在url的末尾添加‘/’
if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"/"]) {
url = [url URLByAppendingPathComponent:@""];
}
self.baseURL = url;
// 3、给requestSerializer、responseSerializer设置默认值
self.requestSerializer = [AFHTTPRequestSerializer serializer];
self.responseSerializer = [AFJSONResponseSerializer serializer];
return self;
}
这里我们主要讨论下一父类的初始化都做了些什么事情
1、初始化session
2、给manager的属性设置初始值
初始化session,defaultSessionConfiguration
self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];
初始属性
// 默认为json解析
self.responseSerializer = [AFJSONResponseSerializer serializer];
// 设置默认证书 无条件信任证书https认证
self.securityPolicy = [AFSecurityPolicy defaultPolicy];
#if !TARGET_OS_WATCH
// 网络状态监听
self.reachabilityManager = [AFNetworkReachabilityManager sharedManager];
#endif
// delegate= value taskid = key
//可变字典,key是NSURLSessionTask的唯一NSUInteger类型标识,value是对应的AFURLSessionManagerTaskDelgate对象
self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init];
调用get方法
1.在生成request的时候处理了监听request的属性变化;
2.参数转查询字符串;
3.生成任务安全;
4.通过AFURLSessionManagerTaskDelegate使得我们的进度可以通过block回调;
5.通过AFURLSessionManagerTaskDelegate拼接我们的服务器返回数据
这里要说一个重要的方法
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlock
downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock
completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler {
//1、为了解决iOS8一下的一个bug,调用一个串行队列来创建dataTask
__block NSURLSessionDataTask *dataTask = nil;
url_session_manager_create_task_safely(^{
//原生的方法
//使用session来创建一个NSURLSessionDataTask对象
dataTask = [self.session dataTaskWithRequest:request];
});
//2、为什么要给task添加代理呢?
[self addDelegateForDataTask:dataTask uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:completionHandler];
return dataTask;
}
这里为什么要给task添加代理呢?
请求大致分三步
1、发起请求
2、请求过程
3、请求完成
第一步sessionManager完成,后两步通过delegate完成。这样的设计,减少了主类(sessionManager)的复杂度,提高了代码的维护性
//为task设置关联的delegate
- (void)setDelegate:(AFURLSessionManagerTaskDelegate *)delegate
forTask:(NSURLSessionTask *)task
{
//task和delegate都不能为空
NSParameterAssert(task);
NSParameterAssert(delegate);
//加锁确保中间代码块是原子操作,线程安全
[self.lock lock];
//将delegate存入字典,以taskid作为key,说明每个task都有各自的代理
self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)] = delegate;
//设置两个NSProgress的变量 - uploadProgress和downloadProgress,给session task添加了两个KVO事件
[delegate setupProgressForTask:task];
[self addNotificationObserverForTask:task];
[self.lock unlock];
}
这里通过添加KVO实现对任务中数据传输的过程监听,通过通知来监听整个任务执行结果
网友评论