第三方框架|第三方框架 | 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 概述(一)
推荐阅读
- android第三方框架(五)ButterKnife
- 标签、语法规范、内联框架、超链接、CSS的编写位置、CSS语法、开发工具、块和内联、常用选择器、后代元素选择器、伪类、伪元素。
- thinkphp|thinkphp 3.2 如何调用第三方类库
- Android7.0|Android7.0 第三方应用无法访问私有库
- Spring|Spring 框架之 AOP 原理剖析已经出炉!!!预定的童鞋可以识别下发二维码去看了
- 构建App(一)(框架与结构)
- laravel框架泛解
- iOS常用第三方库
- spring事务管理_01:事务管理框架+声明式事务
- Java集合框架|Java集合框架 数据结构