这篇文章不利于学习使用,技术能力有限,希望和大家多多沟通。如有错误,请多多指教。
解析AFNetWorking的一次完整的GET请求。
请求发起->代码块回调的基本流程。
AFNetWorking请求.png步骤:
1. 创建manager
(AFHTTPSessionManager
)对象
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
首先需要初始化一个AFHTTPSessionManager
的对象。
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
在初始化AFHTTPSessionManager
这个对象的时候,AFNetWorking
做了些什么呢~
- 配置基础域名:
baseUrl
- 创建请求序列化对象:
requestSerializer
(AFHTTPRequestSerializer
)- 创建返回参数序列化对象:
responseSerializer
(AFJSONResponseSerializer
)- 使用这个
self = [super initWithSessionConfiguration:configuration]
初始化manager
的以下配置:
PS:manager
为AFHTTPSessionManager
的对象,其父类AFURLSessionManager
sessionConfiguration
(NSURLSessionConfiguration
) 请求配置。例如:请求id,超时operationQueue
(NSOperationQueue
) 请求线程队列,用于控制最大请求个数self.operationQueue.maxConcurrentOperationCount= 1
; 设置最多允许1一个请求执行session
(NSURLSession
)请求会话对象securityPolicy
(AFSecurityPolicy
)加密协议reachabilityManager
(AFNetworkReachabilityManager
)网络监听mutableTaskDelegatesKeyedByTaskIdentifier
(NSMutableDictionary
)请求队列,Key:请求标识 Value:manager
的代理lock
(NSLock
)线程锁,保证请求队列的读取。mutableTaskDelegatesKeyedByTaskIdentifier
- 分别对
dataTasks
、uploadTasks
、downloadTasks
绑定数据响应回调。创建delegate
(AFURLSessionManagerTaskDelegate
)绑定三个block
用于回调completionHandler
,uploadProgressBlock
,downloadProgressBlock
。
2.发起请求
[manager GET:@"<#请求地址#>" parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {
//文件下载回调
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//请求成功回调
NSLog(@"请求已完成.数据回调线程%@",[NSThread currentThread]);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//请求失败回调。
NSLog(@"请求失败:%@",error.description);
}];
3.封装NSURLSessionDataTask
任务
- 创建请求会话:(
NSMutableURLRequest
)- 使用
request
(NSMutableURLRequest
)对象,创建DataTask
(NSURLSessionDataTask
)对象。
//创建请求会话
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method
URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString]
parameters:parameters
error:&serializationError];
//创建任务会话
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);
}
}
}];
4.开启请求
[dataTask resume];
5.请求完成,代理回调
请求完成,
NSURLSessionTaskDelegate
代理回调。
- (void)URLSession:(__unused NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
//请求完成,代理回调
}
6.通知manager
任务完成
异步任务,主队列发送通知:
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo];
});
AFNetworkingTaskDidCompleteNotification
具体的标识:" com.alamofire.networking.task.complete
"。在AFNetworkActivityIndicatorManager
类中,有一个控制请求并发个数的操作。当前请求完成,通知AFNetworkActivityIndicatorManager
可以进行下一个请求。
7.请求完成,代码块回调请求结果
//url_session_manager_processing_queue 单利并发队列
dispatch_async(url_session_manager_processing_queue(), ^{
NSError *serializationError = nil;
responseObject = [manager.responseSerializer responseObjectForResponse:task.response data:data error:&serializationError];
if (self.downloadFileURL) {
responseObject = self.downloadFileURL;
}
if (responseObject) {
userInfo[AFNetworkingTaskDidCompleteSerializedResponseKey] = responseObject;
}
if (serializationError) {
userInfo[AFNetworkingTaskDidCompleteErrorKey] = serializationError;
}
//主队列回调任务。
dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{
if (self.completionHandler) {
self.completionHandler(task.response, responseObject, serializationError);
}
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo];
});
});
});
manager.completionGroup
和manager.completionQueue
是可以设置的。代表数据返回的组和队列。
NSLog(@"发起请求线程:%@",[NSThread currentThread]);
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//数据返回组
dispatch_group_t customGroup = dispatch_group_create();
//数据返回队列
dispatch_queue_t customQueue = dispatch_queue_create("networking.dataForBack", DISPATCH_QUEUE_SERIAL);
manager.completionGroup = customGroup;
manager.completionQueue = customQueue;
[manager GET:@"http://apps.lianziapp.com:8020/common/config/getSystemConfig" parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {
NSLog(@"请求进度:%@",downloadProgress.localizedDescription.description);
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//NSLog(@"请求成功:%@",responseObject);
NSLog(@"请求已完成.数据回调线程%@",[NSThread currentThread]);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"请求失败:%@",error.description);
NSLog(@"当前请求任务:%@",task);
}];
输出:
发起请求线程:<NSThread: 0x60000340c100>{number = 1, name = main}
请求已完成.数据回调线程<NSThread: 0x600003456340>{number = 5, name = (null)}
可以看出,数据回调线程和主线程不一致。说明队列和组的设置成功了(串行队列+异步任务开启子线程)。这个参数没有设置的话,结果会直接返回主线程。
至此请求完成。
结束。
网友评论