简介
AFNetworking4.0 是对NSURLSession的封装,之前版本有NSURLConnection的封装,现在已经被废弃。
简单聊一下,为啥AF要弃用之前的NSURLConnection封装,改成对NSURLSession封装。
首先,NSURLSession是在iOS7.0的时候苹果推出来的。而NSURLSession又能支持Http2.0的。大家都知道Http是基于TCP协议的,早期的Http是短连接的,每次传输数据都需要重新连接,而每次连接的话需要进行三次握手,这就造成了资源以及时间的浪费。然后,在Http2.0的时候更新了Connection:keep-alive选项,这个优化项,使客户端与服务器在相同config的时候复用了同一个TCP连接,减少了每次请求的时间,提升了数据的传输速率。所以,AFNetworking也果断的改变成对NSURLSession的封装。
AFNetworking的五大模块
AFNetworking这个三方库主要包含以下五大模块:
- NSURLSession 网络通信模块
- Reachability 网络状态监听模块
- Security 网络通讯安全策略模块
- Serialization 序列化模块
- UIKit 对UIKit的扩展模块
下边主要讲的是在使用过程中,初始化过程以及请求方法内部实现过程
初始化
首先,AFHttpSessonManager继承自AFURLSessonManager。
当我们调用初始化方法[AFHTTPSessionManager manager],看代码里边都做了哪些事情呢?
- (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;
}
⚠️:虽然AF起名manager,但是,内部实现并不是一个单例,而是每次都会创建一个新的HttpSessonManager对象。
- 首先会先调用父类(AFURLSessonManager)的初始化方法。
- 给URL进行格式化处理,添加“/”
- 设置requestSerializer和responseSerializer
其中父类(AFURLSessonManager)的初始化方法主要设置了configuration,并且通过设置maxConcurrentOperationCount = 1设置了一个串行队列。以及解析的方式、网络状态的监听并创建了一个lock来保证线程安全等。
Request方法
- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(nullable id)parameters
headers:(nullable NSDictionary <NSString *, NSString *> *)headers
uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgress
downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress
success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure
{
NSError *serializationError = nil;
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];
for (NSString *headerField in headers.keyEnumerator) {
[request setValue:headers[headerField] forHTTPHeaderField:headerField];
}
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;
}
在这个方法里,AF返回了一个dataTask对象。大致又做了哪些事情呢?
-
先通过requestwithmethod方法获取一个request对象,获取这个对象的时候,通过请求方法的请求类型get、head、delete来判断是将参数直接拼接到url后边还是添加到body里。
-
然后通过方法dataTaskWithRequest方法,将上边的request生成一个task对象。其中addDelegateForDataTask中将task和delegate绑定到一起。每个task有相对应的代理。
在具体请求方法(post、get、delete、put等)里,对返回的task对象调用[dataTask resume];方法。
[dataTask resume]
这是进行网络请求的最后一步,AF在父类中,对系统的resume方法通过method_exchangeImplementations方法与自定义的af_resume方法进行交换。并在自定义的af_resume方法里对各种结果状态通过AFNSURLSessionTaskDidResumeNotification通知。