一、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子类,除了父类功能外,还有以下作用:

        1、设置requestSerializer

        2、根据不同请求方式生成NSURLSessionDataTask

三、AFURLRequestSerialization

        是生成NSURLRequest的协议,主要针对AFHTTPSessionManager的requestSerializer

        AFURLRequestSerialization协议实现类为:AFHTTPRequestSerializer,除了帮我们生成

        NSURLRequest外,还可以设置stringEncoding、allowsCellularAccess、cachePolicy、

        HTTPRequestHeaders等一些请求相关的参数

        AFHTTPRequestSerializer有2个子类(主要用于不同的`Content-Type`):

        AFJSONRequestSerializerapplication/json

        AFPropertyListRequestSerializerapplication/xplist

        在处理multipart/formdata方式时,提供了方法

- (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):

        AFJSONResponseSerializerjson解析

        AFXMLParserResponseSerializerxml解析,返回NSXMLParser)

        AFXMLDocumentResponseSerializerxml解析,返回NSXMLDocument)

        AFPropertyListResponseSerializer(plist解析)

        AFImageResponseSerializer图片解析)

        AFCompoundResponseSerializer组合解析,可以添加多个上面类,根据顺序解析)

五、AFURLSessionManagerTaskDelegate

        真正的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:&amp;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 &amp;&amp; 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:&amp;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进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注