美文网首页
AFNetWorking一次完整的GET请求剖析

AFNetWorking一次完整的GET请求剖析

作者: 低音区 | 来源:发表于2020-08-07 15:51 被阅读0次

    这篇文章不利于学习使用,技术能力有限,希望和大家多多沟通。如有错误,请多多指教。
    解析AFNetWorking的一次完整的GET请求。

    请求发起->代码块回调的基本流程。

    AFNetWorking请求.png

    步骤:

    1. 创建manager(AFHTTPSessionManager)对象

    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    

    首先需要初始化一个AFHTTPSessionManager的对象。

    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    

    在初始化AFHTTPSessionManager这个对象的时候,AFNetWorking做了些什么呢~

    • 配置基础域名:baseUrl
    • 创建请求序列化对象:requestSerializer(AFHTTPRequestSerializer)
    • 创建返回参数序列化对象:responseSerializerAFJSONResponseSerializer
    • 使用这个self = [super initWithSessionConfiguration:configuration]初始化manager的以下配置:
      PS:managerAFHTTPSessionManager的对象,其父类AFURLSessionManager
    • sessionConfiguration (NSURLSessionConfiguration) 请求配置。例如:请求id,超时
    • operationQueueNSOperationQueue请求线程队列,用于控制最大请求个数
    • self.operationQueue.maxConcurrentOperationCount= 1 ; 设置最多允许1一个请求执行
    • sessionNSURLSession请求会话对象
    • securityPolicyAFSecurityPolicy加密协议
    • reachabilityManagerAFNetworkReachabilityManager网络监听
    • mutableTaskDelegatesKeyedByTaskIdentifierNSMutableDictionary请求队列,Key:请求标识 Value:manager的代理
    • lock(NSLock线程锁,保证请求队列的读取。mutableTaskDelegatesKeyedByTaskIdentifier
    • 分别对dataTasksuploadTasksdownloadTasks绑定数据响应回调。创建delegateAFURLSessionManagerTaskDelegate)绑定三个block用于回调completionHandleruploadProgressBlockdownloadProgressBlock

    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
    • 使用requestNSMutableURLRequest)对象,创建DataTaskNSURLSessionDataTask)对象。
    //创建请求会话
    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.completionGroupmanager.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)}
    

    可以看出,数据回调线程和主线程不一致。说明队列和组的设置成功了(串行队列+异步任务开启子线程)。这个参数没有设置的话,结果会直接返回主线程。
    至此请求完成。

    结束。

    相关文章

      网友评论

          本文标题:AFNetWorking一次完整的GET请求剖析

          本文链接:https://www.haomeiwen.com/subject/spkfdktx.html