AFNetworking网络请求详解

一、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`):

        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、

              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];
                });
            });
        });
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值