网络请求的核心类,主要作用有以下几点:
1、线程安全的创建NSURLSession,并实现NSURLSessionDelegate
2、设置responseSerializer(用于返回数据的解析,默认AFJSONResponseSerializer)
设置securityPolicy(用于SSL证书,HTTPS访问安全管理)
设置completionQueue(请求完成返回数据时的队列,不设置默认回到主线程队列)
设置completionGroup(请求完成返回数据时的队列组,不设置会使用默认值)
设置reachabilityManager(用于网络状况的监控)
3、生成各类NSURLSessionTask,以及设置各类Task的回调Block。
NSURLSessionDataTask、NSURLSessionUploadTask、NSURLSessionDownloadTask
4、管理AFURLSessionManagerTaskDelegate,根据Task标识,把NSURLSessionDelegate
回调分发到具体的AFURLSessionManagerTaskDelegate对象中
是AFURLSessionManager子类,除了父类功能外,还有以下作用:
1、设置requestSerializer
2、根据不同请求方式生成NSURLSessionDataTask
是生成NSURLRequest的协议,主要针对AFHTTPSessionManager的requestSerializer
AFURLRequestSerialization协议实现类为:AFHTTPRequestSerializer,除了帮我们生成
NSURLRequest外,还可以设置stringEncoding、allowsCellularAccess、cachePolicy、
HTTPRequestHeaders等一些请求相关的参数。
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
formData))block - error:(NSError * _Nullable __autoreleasing *)error;
在constructingBodyWithBlock中提供了实现AFMultipartFormData协议的类用于添加参数
AFMultipartFormData真正的实现类是AFStreamingMultipartFormData
是解析Response的协议,实现类为:AFHTTPResponseSerializer
AFHTTPResponseSerializer有以下几个子类(用于解析不同的MIMEType):
AFJSONResponseSerializer(json解析)
AFXMLParserResponseSerializer(xml解析,返回NSXMLParser)
AFXMLDocumentResponseSerializer(xml解析,返回NSXMLDocument)
AFPropertyListResponseSerializer(plist解析)
AFImageResponseSerializer(图片解析)
AFCompoundResponseSerializer(组合解析,可以添加多个上面类,根据顺序解析)
真正的NSURLSessionDelegate实现类,用于管理Task的上传下载进度,完成回调等
1、准备工作。初始化AFHTTPSessionManager,并根据业务设置requestSerializer、
responseSerializer、baseUrl等
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];
- });
- });
- });
- }
- }