ios AFNetworking 3.0 源码阅读分析 (四)(完结篇&&AFHTTPSessionManager模块)

  到现在已经写到第四篇了,要到完结的时候了,这篇主要要介绍以下两部分内容:

1、AFNetworing整体交互简介

2、AFHTTPSessionManager模块


 AFNetworing整体交互简界

 对于这部分内容,我会用一个交互图去说明,如下:

在用户使用AFNetworking的正常流程中,上图中实线表示必定会出现步骤,虚线表示有可能出现的步骤。从图中我们就可以看到AFHTTPSessionManager是连接各个模块的核心桥梁。那么接下来就是详细了解AFHTTPSessionManager的功能及作用。


 


 AFHTTPSessionManager模块

接下来就是介绍AFHTTPSessionManager了,先看以下类图

这里重点讲解和记录一下AFURLSessionManager、AFHTTPSessionManager、AFURLSessionManagerTaskDelegate、NSURLSessionTask关系。

如果想了解其它各子模块可参考我前面三篇文章:AFURLRequestSerialization模块AFSecurityPolicy模块AFURLResponseSerialization模块

一个SessionManager它会有一个NSURLSession,从图中可以一个SessionManager可以对应0..*个NSURLSessionTask和0..*AFURLSessionManagerTaskDelegate,NSURLSessionTask和AFURLSessionManagerTaskDelegate它们两个的数量一定是相同的。NSURLSessionTask就是由SessionManager里面的NSURLSession创建出来的。还有在图中我们可以看到SessionManager它实现了四个NSURLSessionXXX的代理。其实它内部有时候是什么都没做,都转给了AFURLSessionManagerTaskDelegate,AFURLSessionManagerTaskDelegate其实也实现了相同的代理,因为画不下没有画到上面。SessionManager只是做了个中转者,真正实现功能的是AFURLSessionManagerTaskDelegate。每当有一个新的任务,都会创建一个对应的AFURLSessionManagerTaskDelegate,并且以task的@(taskIdentifier)作为key,AFURLSessionManagerTaskDelegate作为值保存在字典里,看源码

- (void)setDelegate:(AFURLSessionManagerTaskDelegate *)delegate
            forTask:(NSURLSessionTask *)task
{
    NSParameterAssert(task);
    NSParameterAssert(delegate);

    [self.lock lock];
    self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)] = delegate;
    [delegate setupProgressForTask:task];
    [self addNotificationObserverForTask:task];
    [self.lock unlock];
}

当task有变化或者需要它的代理(其实就是SessionManager)处理时,有需要的话SessionManager就根据taskIdentifier拿到对应的AFURLSessionManagerTaskDelegate让它处理,这里列出其中一个,其它原理都一样:

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

当然有一些是不需要AFURLSessionManagerTaskDelegate处理的。其实我们搜一下delegateForTask:就知道有哪些时候SessionManager依赖了AFURLSessionManagerTaskDelegate。既然这样,我们不妨详细看一下AFURLSessionManagerTaskDelegate有实现些什么样的功能。

@interface AFURLSessionManagerTaskDelegate : NSObject <NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate>
@property (nonatomic, weak) AFURLSessionManager *manager;
//保存接收到的数据
@property (nonatomic, strong) NSMutableData *mutableData;
//如果是上传任务,上传进度
@property (nonatomic, strong) NSProgress *uploadProgress;
//如果是下载,下载进度
@property (nonatomic, strong) NSProgress *downloadProgress;
//下载路径
@property (nonatomic, copy) NSURL *downloadFileURL;
//下载完毕后根据block的返回值把内容移到对应的路径下
@property (nonatomic, copy) AFURLSessionDownloadTaskDidFinishDownloadingBlock downloadTaskDidFinishDownloading;
//回调给外部上传的进度
@property (nonatomic, copy) AFURLSessionTaskProgressBlock uploadProgressBlock;
//回调给外部下载的进度
@property (nonatomic, copy) AFURLSessionTaskProgressBlock downloadProgressBlock;
//完成时回调给外部
@property (nonatomic, copy) AFURLSessionTaskCompletionHandler completionHandler;
@end

我们看它的头文件就可以知道它大概做了些什么了。还有它比较关键的方法- (void)setupProgressForTask:(NSURLSessionTask *)task。从里面源码可以看到对于进度的获取方式和更新都是采了KVC的方法。到这AFHTTPSessionManager也基本介绍完毕了。整体流程明白后其它的应该没什么难度了,其它细节留给读者去挖掘了,还有例如NSURLSession及NSURLSessionTask这些系统相关的使用方法也并没有介绍。


  到这里AFNetworking的主体框架及其模块的内容基本介绍完毕,当然不能面面俱到,希望对大家有帮助。AF还有个UIKit+AFNetworking也是非常值的去刨它的源码,相信也能学习到不多的东西,有时间再写这方面的。

原文地址:https://www.cnblogs.com/chenxianming/p/5713793.html