AFNetworking源码解析

本文分两个章来讲
第一章介绍 NSURLSession
第二章对AFNtworking 源码流程分析

AFNetworking 是一个对NSURLSession高度封装的网络请求工具,所以先简单介绍一下NSURLSession及其用法;第二章再看AFNetworking 源码的时候不会懵;

1.1 NSURLSession

* NSURLSession支持http2.0协议

* iOS9.0之后使用的NSURLConnection(iOS9.0之后过期)

* 处理下载任务的时候可以直接把数据下载到磁盘中

* 支持后台下载和上传

* 同一个session发送多次请求,只需要建立一次连接(复用了TCP)

* 提供了全局的session并且可以统一配置,使用更加方便

* 下载的时候是多线程异步处理,效率更高

1.2 NSURLSessionTask

* NSURLSessionTask本身是一个抽象类,在使用的时候,通常是根据具体的需求使用它的几个子类

* NSURLSessionDataTask可以用来发送常见的Get,Post请求,既可以用来上传也可以用来下载

* NURLSessionDownloadTask可以用来发送下载请求,专门用来下载数据

* NSURLSessionUploadTask可以用来发送上传请求,专门用来上传数据

1.3案例 (利用NSURLSession发送get请求)

/* 这里抓了[喜马拉雅]的请求*/
-(void)test1{
  /* 创建URL*/
  NSURL *url = [NSURL   URLWithString:@"http://mobile.ximalaya.com/dog-portal/checkOld/ios_remote/1583898209.875697?signature=34dc9a17ee0c44faac51f9db4ee22aac"];
  /* 创建request*/
  NSURLRequest *request = [NSURLRequest requestWithURL:url];
  /*创建一个session 管理tastk请求任务*/
  NSURLSession *sharedSession = [NSURLSession sharedSession];
  /* 创建task任务*/
  NSURLSessionDataTask *getTask = [sharedSession dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
         
        NSLog(@"get responseData:%@",[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
   }];
  /* 执行task*/
  [getTask resume];
 }
----------------------------------------------------------------------
/*运行结果*/
 runtime[38079:5401322] delegate response didReceiveData:{
    msg = 5;
    ret = 5;
}

1.4案例(利用NSURLSession发送POST请求)

/* 这里抓了[喜马拉雅]的请求*/
-(void)test2{
  NSURL *url_post = [NSURL URLWithString:
                @"http://mobile.ximalaya.com/football-portal/diff2/batch?appId=1&groupNames=ios%2Cfufei%2Ctoc%2Caccount%2Clive%2Csys%2Ctob%2Cad%2Ccommunity%2Cmermaid%2Capm&ts=1583898210&signature=b87c2373ba38307c780fb19a3e52e537"];
  NSMutableURLRequest *request_post = [NSMutableURLRequest 
                                    requestWithURL:url_post];
  request_post.HTTPMethod = @"POST";
  request_post.HTTPBody = [@"name=jack&password=123" 
                               dataUsingEncoding:NSUTF8StringEncoding];
  NSURLSession *shareSession = [NSURLSession sharedSession];
  NSURLSessionDataTask *task_post = [shareSession dataTaskWithRequest:request_post completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

      NSLog(@"post responseData:%@",[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
  }];

  [task_post resume];
}
----------------------------------------------------------------------
/*运行结果*/
runtime[33254:4904562] post responseData:{
    msg = 5;
    ret = 5;
}

1.5案例(通过代理获取请求的结果)

-(void)test3{
    NSURL *url = [NSURL URLWithString:@"http://mobile.ximalaya.com/dog-portal/checkOld/ios_remote/1583898209.875697?signature=34dc9a17ee0c44faac51f9db4ee22aac"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration
    defaultSessionConfiguration];
    /*创建session 并设置代理为 self (self 为当前ViewController)*/
    NSURLSession *session = [NSURLSession
    sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    NSURLSessionDataTask *task = [session
    dataTaskWithRequest:request];
    [task resume];
}

/* 1.接收到服务器响应的时候调用该方法*/
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler{
    
    self.mData = [NSMutableData data];
    completionHandler(NSURLSessionResponseAllow);
}


/* 2.接收到服务器返回数据的时候会调用该方法,如果数据较大那么该方法可能会调用多次*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{
    
      /*拼接服务器返回的数据 */
     [_mData appendData:data];
     NSLog(@"delegate response didReceiveData:%@",[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]);
}

/* 3.当请求完成(成功|失败)的时候会调用该方法,如果请求失败,则error有值*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
    
    /* 解析服务器返回的数据*/
    /*因为此处返回的数据是JSON格式的,因此使用NSJSONSerialization进行反序列化处理*/
    /* AFN中 只接受数据,交给responseSerializer 来处理*/
    NSLog(@"delegate response didCompleteWithError:%@",[NSJSONSerialization JSONObjectWithData:_mData options:kNilOptions error:nil]);
}

----------------------------------------------------------------------
/* 运行结果*/
/*该打印是didReceiveData 代理方法的(因为数据比较小,所以一次可以解析)*/
runtime[33254:4904562] delegate response didReceiveData:{
    msg = 5;
    ret = 5;
}

/*该打印是 didCompleteWithError 代理方法打印的,获取的整个Data 数据*/
 runtime[33254:4904562] delegate response didCompleteWithError:{
    msg = 5;
    ret = 5;
}

2. AFNetworking 开讲

在看文章的同时,可以看我画的这张时序图,希望读者能通过该图对AFNetworking 网络请求的逻辑流程有一个清晰的认识(这个图花了我好几个小时画);

AFNetworking时序图.jpg

众所周知,AFNetworking实现了http 网络请求的 GETHEADPOSTPUTPATCHDELETE等方法,且提供了监听网络进度的block、失败的block、失败的block,其核心就是AFHTTPSessionManager这个类;

AFHTTPSessionManager 主要实现了不同网络请求的调度和网安全策略的可配置、请求序列的可以配置、相映序列的可配置操作;

AFURLSessionManagerAFHTTPSessionManager的父类,实现了更管理task请求任务的管理工作,及数据响应处理的操作。

AFNetworking 提供了securityPolicyrequestSerializerresponseSerializer等参数方便开发者扩展以及自定义 ,以适配不同的服务端。

2.1 源码解析开始喽

当我们使用AFHTTPSessionManager时候,第一件事就是初始化这个类,因为这是一个单例,我们来看一下 AFHTTPSessionManager 初始化的时候都做了哪些事情;

  • (1) 调用父类的 - (instancetype)initWithSessionConfiguration: 方法;
  • (2) 配置URL(如果URL不为null)
  • (3) 初始化requestSerializer 属性为 默认配置 [AFHTTPRequestSerializer serializer]
  • (4)初始化AFJSONResponseSerializer 为 [AFJSONResponseSerializer serializer]

代码如下

- (instancetype)initWithBaseURL:(NSURL *)url
           sessionConfiguration:(NSURLSessionConfiguration *)configuration
{
    self = [super initWithSessionConfiguration:configuration];
    if (!self) {
        return nil;
    }

    // Ensure terminal slash for baseURL path, so that NSURL +URLWithString:relativeToURL: works as expected
    if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"/"]) {
        url = [url URLByAppendingPathComponent:@""];
    }

    self.baseURL = url;

    self.requestSerializer = [AFHTTPRequestSerializer serializer];
    self.responseSerializer = [AFJSONResponseSerializer serializer];

    return self;
}

因为AFHTTPSessionManager 调用了父类的初始化方法,我们看一下 AFURLSessionManager 初始化的时候做了哪些事情:

  • (1)初始化会话配置(session configuration),默认为defaultSessionConfiguration
  • (2)初始化队列,设置队列的最大并发数1
  • (3)初始化会话session,并将session的代理对象设置为self,并将代理队列(设置代理很重要)。
  • (4)初始化 responseSerializer 并设置为默认[AFJSONResponseSerializer serializer]
  • (5) 初始化securityPolicy 安全策略
  • (6) 初始化网络状态监控(watch_OS)
  • (7) 初始化mutableTaskDelegatesKeyedByTaskIdentifier 字典(很重要)
  • (8)初始化线程锁
  • (9)最后一大坨代码是为已经存在的task设置delegate(也很重要)
- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration {
    self = [super init];
    if (!self) {
        return nil;
    }

    if (!configuration) {
        configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    }

    self.sessionConfiguration = configuration;

    self.operationQueue = [[NSOperationQueue alloc] init];
    self.operationQueue.maxConcurrentOperationCount = 1;

    self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];

    self.responseSerializer = [AFJSONResponseSerializer serializer];

    self.securityPolicy = [AFSecurityPolicy defaultPolicy];

#if !TARGET_OS_WATCH
    self.reachabilityManager = [AFNetworkReachabilityManager sharedManager];
#endif

    self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init];

    self.lock = [[NSLock alloc] init];
    self.lock.name = AFURLSessionManagerLockName;

    [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
        for (NSURLSessionDataTask *task in dataTasks) {
            [self addDelegateForDataTask:task uploadProgress:nil downloadProgress:nil completionHandler:nil];
        }

        for (NSURLSessionUploadTask *uploadTask in uploadTasks) {
            [self addDelegateForUploadTask:uploadTask progress:nil completionHandler:nil];
        }

        for (NSURLSessionDownloadTask *downloadTask in downloadTasks) {
            [self addDelegateForDownloadTask:downloadTask progress:nil destination:nil completionHandler:nil];
        }
    }];

    return self;
}

POST请求为例子,平时大家的写法基本是这样子的。
示例代码如下:

  /* 向http://www.xxx.com/path/request 发送一个post 请求,参数为 @{} */
     NSURLSessionDataTask *task = [[AFHTTPSessionManager manager ]POST:@"www.xxx.com/path/request" parameters:@{} progress:^(NSProgress * _Nonnull uploadProgress) {
          
      } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
           
      } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
         
    }];

    /* 取消操作*/
    [task cancel];
    /* 取消操作*/
    [task suspend];
    /* 再次执行*/
    [task resume];

点进去查看 -(*) POST: parameters: success: failure:函数的实现;
在这个函数中,做了如下几件事:

  • (1) 调用自身的- (*)POST: parameters: progress: success: failure: 方法 返回一个 NSURLSessionDataTask 对象;

接着往下走看 - (*)POST: parameters: progress: success: failure:函数的实现;
在这个函数中,做了如下几件事:

  • (1) 调用父类AFURLSessionManager的 - (*)dataTaskWithHTTPMethod: URLString: parameters: uploadProgress:downloadProgress: success: failure: 获取SessionDataTask对象;
  • (2) 执行resume 发送网络请求;

SessionDataTask 被外部对象获取,外部对象可对该 SessionDataTask 对象进行cancelsuspendresume 等操作;

代码如下:

/* AFHTTPSessionManager.m 173*/
- (NSURLSessionDataTask *)POST:(NSString *)URLString
                    parameters:(id)parameters
                       success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
                       failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
{
    return [self POST:URLString parameters:parameters progress:nil success:success failure:failure];
}

- (NSURLSessionDataTask *)POST:(NSString *)URLString
                    parameters:(id)parameters
                      progress:(void (^)(NSProgress * _Nonnull))uploadProgress
                       success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
                       failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
{
    /* 该方法调用子类的 dataTaskWithHTTPMethod     方法获取到请求的 NSURLSessionDataTask */
    NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"POST" URLString:URLString parameters:parameters uploadProgress:uploadProgress downloadProgress:nil success:success failure:failure];
    /*开始请求*/
    [dataTask resume];

    return dataTask;
}

进入父类AFURLSessionManager 查看 - (*)dataTaskWithHTTPMethod: URLString: parameters: uploadProgress:downloadProgress: success: failure:函数的实现;
在这个函数中,做了如下几件事:

  • (1) 通过requestSerializer 创建适合的Request请求;
  • (2) 如果request 创建失败,响应failure block;
  • (3) 通过dataTaskWithRequest 方法获取 dataTask 对象;

代码如下:

/* AFURLSessionManager.m  (267行)*/
- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
                                       URLString:(NSString *)URLString
                                      parameters:(id)parameters
                                  uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgress
                                downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress
                                         success:(void (^)(NSURLSessionDataTask *, id))success
                                         failure:(void (^)(NSURLSessionDataTask *, NSError *))failure
{

    /* 对请求的参数进行处理*/
    NSError *serializationError = nil;
    /*self.requestSerializer 在 初始化的时候默认创建(也可外部配置)*/
    NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];
    /* 如果创建失败,进入该if 判断,执行failure block*/
    if (serializationError) {
        if (failure) {
            dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
                failure(nil, serializationError);
            });
        }
        return nil;
    }

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

    return dataTask;
}

接着往下走看一下 - (*)dataTaskWithRequest: uploadProgress: downloadProgress: completionHandler: 函数的实现;
在这个函数中,做了如下几件事:

  • (1) 线程安全的情况下,创建了一个dataTask对象(这么写是为了解决一个bug issues 链接);
  • (2) 调用自身的 - (void)addDelegateForDataTask: uploadProgress: downloadProgress: completionHandler: 方法, 然后把dataTask、uploadProgressBlock、downloadProgressBlock、completionHandler几个参数传进去;

代码如下:

- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
                               uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlock
                             downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock
                            completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject,  NSError * _Nullable error))completionHandler {

    __block NSURLSessionDataTask *dataTask = nil;
    url_session_manager_create_task_safely(^{
        dataTask = [self.session dataTaskWithRequest:request];
    });

    /* 利用task对创建 AFURLSessionManagerTaskDelegate 对象和manager 的绑定关系*/
    /* 说人话,就是manger 持有多个 AFURLSessionManagerTaskDelegate 对象*/
    /* AFURLSessionManagerTaskDelegate 对象持有task 任务,响应URLSessionTask的代理方法,并响应uploadProgressBlock、 downloadProgressBlock、completionHandler的 block*/
    [self addDelegateForDataTask:dataTask uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:completionHandler];

    return dataTask;
}

接着往下看 - (void)addDelegateForDataTask: uploadProgress: downloadProgress: completionHandler: 函数的实现;

  • (1) 创建AFURLSessionManagerTaskDelegate 对象;
  • (2) delegate和manger 建立持有关系(weak);
  • (3) 调用 - (void)setDelegate: forTask: 方法 ,以task.taskIdentifier 为key , delegate为value 存入manger 的mutableTaskDelegatesKeyedByTaskIdentifier 的可变字典中;
  • (4)赋值completionHandler、uploadProgressBlock、downloadProgressBlock 几个block 给delegate 对象;

再次解释一下

delegate 表示 AFURLSessionManagerTaskDelegate 对象;

AFURLSessionManager 对象通过delegate 来对task任务进行管理,因为delegate对象持有task任务 并且实现了URLSessionTask的代理方法,当网络请求发送出去并收到的时候会触发代理方法,获取网络请求的数据,不论成功还是失败都有响应;而且一开始delegate 创建的时候赋值了completionHandler等block,所以代理方法处理完网络请求的数据就就可以调用completionHandler的 block方法了,最后把数据通过completionHandler block 传递出来;

代码如下:

/* AFURLSessionManager.m (584)*/
- (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 来衔接 SessionTask 和manage的关系*/
    AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] initWithTask:dataTask];
    /* delegte 的manger 指向self,也就是多个delegate 通过weak 弱引用manager*/
    delegate.manager = self;
    
    /* task uploadProgressBlock 赋值给delegate 对象的*/
    delegate.completionHandler = completionHandler;

    dataTask.taskDescription = self.taskDescriptionForSessionTasks;
    [self setDelegate:delegate forTask:dataTask];
    /* task uploadProgressBlock 赋值给delegate 对象的*/
    delegate.uploadProgressBlock = uploadProgressBlock;
    /* task downloadProgressBlock 赋值给delegate 对象的*/
    delegate.downloadProgressBlock = downloadProgressBlock;
}

AFURLSessionManagerTaskDelegate 的实现截图如下,可以看出来SessionManagerTaskDelegate对象实现了NSURLSessionTaskDelegateNSURLSessionDataDelegateNSURLSessionDownloadDelegate的代理方法,因为AFNetworking不止有简单的http请求,还有大文件的上传和下载的操作,

611583895456_.pic_hd.jpg

这里只对AFURLSessionManagerTaskDelegate实现代理方法的逻辑做简单分析;
代码如下:

/*
AFURLSessionManagerTaskDelegate 实现了NSURLSessionTaskDelegate代理方法
*/

#pragma mark - NSURLSessionTaskDelegate
- (void)URLSession:(__unused NSURLSession *)session
              task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
{
  /*省略部分代码...*/
  __block id responseObject = nil;
  if (error) {
      
       dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{
       
            /* 如果completionHandler 不为null task.response, responseObject 和 error 信息传递出去*/    
            if (self.completionHandler) {
                self.completionHandler(task.response, responseObject, error);
            }

            此处省略部分代码...
        });
      
  }else{
    /*网络请求不出错的情况*/
    
      dispatch_async(url_session_manager_processing_queue(), ^{
            NSError *serializationError = nil;
            responseObject = [manager.responseSerializer responseObjectForResponse:task.response data:data error:&serializationError];
            
            此处省略部分代码...
        
            dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{
                /* 调用completionHandler block 回传 response,responseObject,error等信息*/
                if (self.completionHandler) {
                    self.completionHandler(task.response, responseObject, serializationError);
                }
                /*主线程发送通知-处理其它逻辑*/
                dispatch_async(dispatch_get_main_queue(), ^{
                    [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo];
                });
            });
        });
      
  }
}

最后- (void)URLSession:(__unused NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error代理方法执行完做了什么事:

  • (1) 调用completionHandler 函数处理网络请求的成功和失败(很重要

注意看代码是不是又回到了最开始,bolck 实现的地方,是不是AFHTTPSessionManager 这个block ,对的,就是这里;

621583896670_.pic_hd.jpg

至此 ,还没有完全结束;
因为AFURLSessionManager- ()initWithSessionConfiguration: 的时候将 NSURLSession 的delegate设置成自己,且实现了 代理方法 - (void)URLSession: task: didCompleteWithError:,所以最后shareManager 最后需解除mutableTaskDelegatesKeyedByTaskIdentifier 可变字典中 key 和value 的绑定关系(key 为 task.taskIdentifier ,value 为 AFURLSessionManagerTaskDelegate 对象);

代码如下:

/* AFURLSessionManager.m (1061 行)*/
- (void)URLSession:(NSURLSession *)session
              task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
{
    /* 通过task 获取 AFURLSessionManagerTaskDelegate 对象*/
    AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:task];
    /* 如果delegate 对象存在,调用 delegate removeDelegateForTask 方法*/
    if (delegate) {
        [delegate URLSession:session task:task didCompleteWithError:error];
        /* 移除 task 的绑定操作*/
        [self removeDelegateForTask:task];
    }
    if (self.taskDidComplete) {
        self.taskDidComplete(session, task, error);
    }
}
/* AFURLSessionManager.m (636 行)*/
- (void)removeDelegateForTask:(NSURLSessionTask *)task {
    NSParameterAssert(task);
    /* 在线程锁安全的情况下*/
    [self.lock lock];
    /*发送移除某个task 的通知*/
    [self removeNotificationObserverForTask:task];
    /*移除self mutableTaskDelegatesKeyedByTaskIdentifier 字典中key   为 task.taskIdentifier ,value 为delegate 对象的键值对*/
    [self.mutableTaskDelegatesKeyedByTaskIdentifier removeObjectForKey:@(task.taskIdentifier)];
    [self.lock unlock];
}

至此 AFNetworking源码的核心流程基本走完了;

额外扩展讲解

AFURLSessionManagerTaskDelegate 还实现的NSURLSessionTaskDelegateNSURLSessionDownloadDelegate代理方法,用来处理上传和下载的网络请求操作;

#pragma mark - NSURLSessionDataDelegate
- (void)URLSession:(__unused NSURLSession *)session
          dataTask:(__unused NSURLSessionDataTask *)dataTask
    didReceiveData:(NSData *)data
{
   省略代码...
}

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
   didSendBodyData:(int64_t)bytesSent
    totalBytesSent:(int64_t)totalBytesSent
totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend{
    
     省略代码...
}

#pragma mark - NSURLSessionDownloadDelegate
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
      didWriteData:(int64_t)bytesWritten
 totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
     省略代码...
}

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
 didResumeAtOffset:(int64_t)fileOffset
expectedTotalBytes:(int64_t)expectedTotalBytes{
     省略代码...
}

- (void)URLSession:(NSURLSession *)session
      downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location{
     省略代码...
}

你可能感兴趣的:(AFNetworking源码解析)