第三方框架|第三方框架 | AFNetworking源码解析(3) 请求过程

上篇文章《第三方框架 | AFNetworking(2) 初始化过程》主要讲了 AFNetworking 的初始化过程,对其结构有了一个整体认知。这篇文章来分析一下 AFNetworking 是如何工作的,即请求执行过程。以 GET 请求为例:

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; [manager GET:@"你的请求地址" parameters:nil headers:nil progress:^(NSProgress * _Nonnull downloadProgress) { // 请求进度回调 } success:^(NSURLSessionDataTask * _Nonnull task, id_Nullable responseObject) { // 请求成功回调 } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { // 请求失败回调 }];

【第三方框架|第三方框架 | AFNetworking源码解析(3) 请求过程】查看一下这个方法,介绍如下:
- (nullable NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(nullable id)parameters headers:(nullable NSDictionary *)headers progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgress success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

该方法用来创建并运行带有“GET”请求的 NSURLSessionDataTask
  • URLString: 用于创建请求URL的URL字符串;
  • parameters: 根据客户机请求序列化程序编码的参数;
  • headers: 附加到此请求的默认标头的标头;
  • downloadProgress: 下载进度更新时要执行的 block 对象。(注意,这个块是在会话队列上调用的,而不是在主队列上);
  • success: 当任务成功完成时要执行的 block 对象,该 block 没有返回值,并接受两个参数:数据任务(NSURLSessionDataTask *task)和客户端响应序列化程序创建的响应对象(id _Nullable responseObject)。
  • failure:当任务未成功完成或任务已成功完成但在解析响应数据时遇到错误时要执行的 block 对象。该 block 没有返回值,并接受两个参数:数据任务(NSURLSessionDataTask *task)和描述网络或解析错误的错误(NSError *error)。
- (NSURLSessionDataTask *)GET:(NSString *)URLString parameters:(id)parameters headers:(nullable NSDictionary *)headers progress:(void (^)(NSProgress * _Nonnull))downloadProgress success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure { // 创建一个 `NSURLSessionDataTask` 对象 NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET" URLString:URLString parameters:parameters headers:headers uploadProgress:nil downloadProgress:downloadProgress success:success failure:failure]; // 运行任务 [dataTask resume]; return dataTask; }

- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method URLString:(NSString *)URLString parameters:(id)parameters headers:(NSDictionary *)headers uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgress downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress success:(void (^)(NSURLSessionDataTask *, id))success failure:(void (^)(NSURLSessionDataTask *, NSError *))failure { // 创建请求 NSError *serializationError = nil; NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError]; for (NSString *headerField in headers.keyEnumerator) { [request addValue:headers[headerField] forHTTPHeaderField:headerField]; } if (serializationError) { if (failure) { dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{ failure(nil, serializationError); }); }return nil; }// 创建任务 __block NSURLSessionDataTask *dataTask = nil; dataTask = [self dataTaskWithRequest:request uploadProgress:uploadProgress downloadProgress:downloadProgress completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) { if (error) { if (failure) { failure(dataTask, error); } } else { if (success) { success(dataTask, responseObject); } } }]; return dataTask; }

上面的方法主要做了两件事,创建请求并通过请求创建一个任务。
- (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 {// 创建任务 __block NSURLSessionDataTask *dataTask = nil; url_session_manager_create_task_safely(^{ dataTask = [self.session dataTaskWithRequest:request]; }); // 设置代理 [self addDelegateForDataTask:dataTask uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:completionHandler]; return dataTask; }

上面的方法主要做了两件事,创建任务并设置代理。
总结 至此,我们用顺藤摸瓜的方式知道了请求执行的整个过程也就是创建和运行 NSURLSessionDataTask 对象的过程:
- [AFHTTPSessionManager GET:parameters:headers:process:success:failure:] - [AFHTTPSessionManager dataTaskWithHTTPMethod:parameters:uploadProgress:downloadProgress:success:failure:] // 返回 NSURLSessionDataTask #1 - [AFHTTPRequestSerializer requestWithMethod:URLString:parameters:error:] // 返回 NSMutableURLRequest - [AFURLSessionManager dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:] // 返回 NSURLSessionDataTask #2 - [NSURLSession dataTaskWithRequest:] // 返回 NSURLSessionDataTask #3 - [AFURLSessionManager addDelegateForDataTask:uploadProgress:downloadProgress:completionHandler:] - [NSURLSessionDataTask resume]

在这里 #1 #2 #3 处返回的是同一个 data task,我们可以看到,在 #3 处调用的方法 - [NSURLSession dataTaskWithRequest:] 和只使用 NSURLSession 发出 HTTP 请求时调用的方法 - [NSURLSession dataTaskWithRequest:completionHandler:] 差不多。在这个地方返回 data task 之后,我们再调用 - resume 方法执行请求,并在某些事件执行时通知代理 AFURLSessionManagerTaskDelegate
参考:AFNetworking 概述(一)

    推荐阅读