iOS AFNetWorking源码详解
首先来介绍下AFNetWorking
,官方介绍如下:
AFNetworking is a delightful networking library for iOS and Mac OS X. It’s built on top of theFoundation URL Loading System, extending the powerful high-level networking abstractions built into Cocoa. It has a modular architecture with well-designed, feature-rich APIs that are a joy to use.
Perhaps the most important feature of all, however, is the amazing community of developers who use and contribute to AFNetworking every day. AFNetworking powers some of the most popular and critically-acclaimed apps on the iPhone, iPad, and Mac.
Choose AFNetworking for your next project, or migrate over your existing projects—you’ll be happy you did!
翻译过来简单来说就是
AFNetworking是一个适用于iOS和Mac OS X两个平台的网络库,它是基于Foundation URL Loading System上进行了一套封装,并且提供了丰富且优美的API接口给使用者使用
相信从star数和fork数来看,大家都能明白这个库是多么的受欢迎了,所以了解这个库对于一个iOS开发来说是极为重要的!
这个是AFNetworking的github地址:GitHub - AFNetworking/AFNetworking: A delightful networking framework for iOS
在使用前阅读README是非常重要的,里面往往包括了这个库的介绍、安装和使用等等,对于快速了解一个库来说,这是非常有帮助的
首先我们在AFNetWorking源码地址里download下来,打开工程文件,可以看到里面内容分为两个部分,一个是AFNetworking
,另一个是UIKit+AFNetworking
很明显,第一个是用来做网络请求相关的,第二个则是和UI使用相关的,我们先看第一个
在看完头文件和README之后,你会发现AFURLSessionManager
和AFHTTPSessionManager
是里面比较重要的两个类
这里我先讲AFURLSessionManager
这个类
首先浏览完这个类从API,发现其主要提供了数据的请求、上传和下载功能
在属性方面:
@property(readonly,nonatomic,strong)NSArray *tasks;
@property(readonly,nonatomic,strong)NSArray *dataTasks;
@property(readonly,nonatomic,strong)NSArray *uploadTasks;
@property(readonly,nonatomic,strong)NSArray *downloadTasks;
通过这四个属性,我们分别可以拿到总的任务集合、数据任务集合、上传任务集合和下载任务集合
@property(nonatomic,assign)BOOL attemptsToRecreateUploadTasksForBackgroundSessions;
这个属性非常重要,注释里面写到,在iOS7中存在一个bug,在创建后台上传任务时,有时候会返回nil,所以为了解决这个问题,AFNetworking遵照了苹果的建议,在创建失败的时候,会重新尝试创建,次数默认为3次,所以你的应用如果有场景会有在后台上传的情况的话,记得将该值设为YES,避免出现上传失败的问题
FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidResumeNotification;
在对外提供的notification key里面,使用了FOUNDATION_EXPORT
来定义常量,使用FOUNDATION_EXPORT
和extern
或者define
有什么区别呢?
FOUNDATION_EXPORT
在c文件编译下是和extern等同,在c++文件编译下是和extern “C”等同,在32位机的环境下又是另外编译情况,在兼容性方面,FOUNDATION_EXPORT
做的会更好。
进入到实现文件里面,我们可以看到在外部API调用dataTask、uploadTask、downloadTask
方法实际上都是completionHanlder block
返回出来的,但是我们知道网络请求是delegate
返回结果的,AF
内部做了巧妙的操作,他对每个task都增加代理设置
- (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里面都会调用addDelegate方法
[self addDelegateForDataTask:dataTask uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:completionHandler];
return dataTask;
}