AFNetworking,是iOS开发中最常用的网络请求框架,使用方法应该就不用我来bb了,这里主要就它的源码进行解读(其实是和大家一起学习啦😁)。先附上原框架github上的地址:https://github.com/AFNetworking/AFNetworking。
第一步我们一起来看下AF的文件目录结构。

AFNetworking Example是使用案例,我们直接忽略就好了。那么我们可以看到主要有两个文件夹,AFNetworking和UIKit+AFNetworking. UIKit + AFNetworking这个文件夹里是UIKit中一些控件的拓展,用于网络请求中的UI交互,有兴趣的可以自己去看下,这里我们也忽略了。重点就是AFNetworking中的文件了。
一、AFURLSessionManager
AFURLSessionManager是AFHTTPSessionManger的基类。它遵循了NSURLSession 和 NSURLSessionTask的一些代理方法,实现了数据的请求、上传和下载功能。
预览一下.h文件,我们可以看到下面这四个只读属性:
@property(readonly,nonatomic,strong)NSArray *tasks;
@property(readonly,nonatomic,strong)NSArray *dataTasks;
@property(readonly,nonatomic,strong)NSArray *uploadTasks;
@property(readonly,nonatomic,strong)NSArray *downloadTasks;
分别代表了总的任务集合、数据任务集合、上传任务集合和下载任务集合。
然后我们再看下几个创建请求任务的方法:
1.创建数据任务
- (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;
2.创建上传任务(有三种方法)
通过fileURL方式上传(上传本地文件的URL路径)
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request
fromFile:(NSURL *)fileURL
progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock
completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler;
通过bodyData方式上传(数据放在请求体httpBody中)
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request
fromData:(nullable NSData *)bodyData
progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock
completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler;
通过流方式上传(此时一定要设置setTaskNeedNewBodyStreamBlock回调,否则session没办法在重新发送steam的时候找到数据源)
- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request
progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressBlock
completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler;
3.创建下载任务(也有两种方式)
通过http方式普通下载
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request
progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock
destination:(nullable NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
completionHandler:(nullable void (^)(NSURLResponse *response, NSURL * _Nullable filePath, NSError * _Nullable error))completionHandler;
另一种则是通过之前的下载数据来恢复下载,destination在下载的过程中文件会先存放在一个临时的位置,等到下载完成之后,文件会转移到目标位置
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData
progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock
destination:(nullable NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
completionHandler:(nullable void (^)(NSURLResponse *response, NSURL * _Nullable filePath, NSError * _Nullable error))completionHandler;
其他一些方法都是设置请求相关的,比如请求失败策略(是否继续请求),获取上传、下载进度progress等。
再来看下.m实现,实现文件里面具体分为三部分:
第一部分:AFURLSessionManagerTaskDelegate
Delegate里面做的内容有:
1、设置task的progress
2、KVO监听task、progress的方法调用
3、实现URLSessionTask的回调,将完成的结果block给manager里面相关的调用方法,并且通知给接收者
4、对接收到的数据进行了拼接
5、对下载完成后的文件进行转移
第二部分:_AFURLSessionTaskSwizzling
这部分主要做的是将NSURLSessionDataTask及父类里的resume和suspend方法替换成自己自定义的方法
第三部分:AFURLSessionManager
1、初始化session配置及增加task代理,通过self.session getTasks得到所有的任务,然后依次设置代理
2、外部API的block通过delegate里面的block来获得