一、AFURLSessionManager
1、线程安全的创建NSURLSession,并实现NSURLSessionDelegate
2、设置responseSerializer(用于返回数据的解析,默认AFJSONResponseSerializer)
设置securityPolicy(用于SSL证书,HTTPS访问安全管理)
设置completionQueue(请求完成返回数据时的队列,不设置默认回到主线程队列)
设置completionGroup(请求完成返回数据时的队列组,不设置会使用默认值)
设置reachabilityManager(用于网络状况的监控)
3、生成各类NSURLSessionTask,以及设置各类Task的回调Block。
NSURLSessionDataTask、NSURLSessionUploadTask、NSURLSessionDownloadTask
4、管理AFURLSessionManagerTaskDelegate,根据Task标识,把NSURLSessionDelegate
回调分发到具体的AFURLSessionManagerTaskDelegate对象中
二、AFHTTPSessionManager
是AFURLSessionManager子类,除了父类功能外,还有以下作用:
2、根据不同请求方式生成NSURLSessionDataTask
三、AFURLRequestSerialization
是生成NSURLRequest的协议,主要针对AFHTTPSessionManager的requestSerializer
AFURLRequestSerialization协议实现类为:AFHTTPRequestSerializer,除了帮我们生成
NSURLRequest外,还可以设置stringEncoding、allowsCellularAccess、cachePolicy、
AFHTTPRequestSerializer有2个子类(主要用于不同的`Content-Type`):
AFJSONRequestSerializer(application/json)
AFPropertyListRequestSerializer(application/x–plist)
在处理multipart/form–data方式时,提供了方法:
- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(nullable NSDictionary <NSString *, id> *)parameters
constructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))block
error:(NSError * _Nullable __autoreleasing *)error;
在constructingBodyWithBlock中提供了实现AFMultipartFormData协议的类用于添加参数
AFMultipartFormData真正的实现类是AFStreamingMultipartFormData
四、AFURLResponseSerialization
是解析Response的协议,实现类为:AFHTTPResponseSerializer
AFHTTPResponseSerializer有以下几个子类(用于解析不同的MIMEType):
AFJSONResponseSerializer(json解析)
AFXMLParserResponseSerializer(xml解析,返回NSXMLParser)
AFXMLDocumentResponseSerializer(xml解析,返回NSXMLDocument)
AFPropertyListResponseSerializer(plist解析)
AFImageResponseSerializer(图片解析)
AFCompoundResponseSerializer(组合解析,可以添加多个上面类,根据顺序解析)
五、AFURLSessionManagerTaskDelegate
真正的NSURLSessionDelegate实现类,用于管理Task的上传下载进度,完成回调等
六、完整的网络请求流程
1、准备工作。初始化AFHTTPSessionManager,并根据业务设置requestSerializer、
2、创建Task,以自定义NSURLSessionDataTask为例:
- (nullable NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(nullable id)parameters
headers:(nullable NSDictionary <NSString *, NSString *> *)headers
uploadProgress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
downloadProgress:(nullable void (^)(NSProgress *downloadProgress))downloadProgress
success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
首页会根据我们设置的requestSerializer生成NSMutableURLRequest:
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 setValue:headers[headerField] forHTTPHeaderField:headerField];
}
如果requestSerializer报错,就结束流程,从completionQueue回调出去,
如果requestSerializer成功,开始生成NSURLSessionDataTask:
__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);
}
}
}];
我们跟着生成的方法点进去看到,通过AFHTTPSessionManager.session生成Task,并且
创建Task的AFURLSessionManagerTaskDelegate和回调参数,同时根据Task的标识存储
Delegate到mutableTaskDelegatesKeyedByTaskIdentifier字典中
NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:request];
[self addDelegateForDataTask:dataTask uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:completionHandler];
- (void)addDelegateForDataTask:(NSURLSessionDataTask *)dataTask
uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlock
downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
{
AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] initWithTask:dataTask];
delegate.manager = self;
delegate.completionHandler = completionHandler;
dataTask.taskDescription = self.taskDescriptionForSessionTasks;
[self setDelegate:delegate forTask:dataTask];
delegate.uploadProgressBlock = uploadProgressBlock;
delegate.downloadProgressBlock = downloadProgressBlock;
}
- (void)setDelegate:(AFURLSessionManagerTaskDelegate *)delegate
forTask:(NSURLSessionTask *)task
{
NSParameterAssert(task);
NSParameterAssert(delegate);
[self.lock lock];
self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)] = delegate;
[self addNotificationObserverForTask:task];
[self.lock unlock];
}
3、启动Task,使用resume方法。而后通过NSURLSessionDelegate监听网络请求过程。我们
可以看到AFURLSessionManager实现的NSURLSessionDelegate方法中,首先根据task
标识获取对应的AFURLSessionManagerTaskDelegate,然后分发事件至具体的Delegate
类中。我们以didCompleteWithError回调看:
- (void)URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
{
AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:task];
// delegate may be nil when completing a task in the background
if (delegate) {
[delegate URLSession:session task:task didCompleteWithError:error];
[self removeDelegateForTask:task];
}
if (self.taskDidComplete) {
self.taskDidComplete(session, task, error);
}
}
4、请求完成回调处理,实际是在AFURLSessionManagerTaskDelegate中实现的,通过阅读
代码实现可以看出如果请求出现错误,就回调到completionHandler,如果未出现错误,
首先获取manager的responseSerializer去解析返回内容,然后再回调出去
- (void)URLSession:(__unused NSURLSession *)session
task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
{
error = objc_getAssociatedObject(task, AuthenticationChallengeErrorKey) ?: error;
__strong AFURLSessionManager *manager = self.manager;
__block id responseObject = nil;
NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];
userInfo[AFNetworkingTaskDidCompleteResponseSerializerKey] = manager.responseSerializer;
//Performance Improvement from #2672
NSData *data = nil;
if (self.mutableData) {
data = [self.mutableData copy];
//We no longer need the reference, so nil it out to gain back some memory.
self.mutableData = nil;
}
#if AF_CAN_USE_AT_AVAILABLE && AF_CAN_INCLUDE_SESSION_TASK_METRICS
if (@available(iOS 10, macOS 10.12, watchOS 3, tvOS 10, *)) {
if (self.sessionTaskMetrics) {
userInfo[AFNetworkingTaskDidCompleteSessionTaskMetrics] = self.sessionTaskMetrics;
}
}
#endif
if (self.downloadFileURL) {
userInfo[AFNetworkingTaskDidCompleteAssetPathKey] = self.downloadFileURL;
} else if (data) {
userInfo[AFNetworkingTaskDidCompleteResponseDataKey] = data;
}
if (error) {
userInfo[AFNetworkingTaskDidCompleteErrorKey] = error;
dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{
if (self.completionHandler) {
self.completionHandler(task.response, responseObject, error);
}
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo];
});
});
} else {
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];
});
});
});
}
}
原文地址:https://blog.csdn.net/PeaksLee/article/details/126779290
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_10163.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!