解读AFNetworking4.0请求原理

2023-05-16

简介

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对象。

  1. 首先会先调用父类(AFURLSessonManager)的初始化方法。
  2. 给URL进行格式化处理,添加“/”
  3. 设置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对象。大致又做了哪些事情呢?

  1. 先通过requestwithmethod方法获取一个request对象,获取这个对象的时候,通过请求方法的请求类型get、head、delete来判断是将参数直接拼接到url后边还是添加到body里。

  2. 然后通过方法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通知。

 

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

解读AFNetworking4.0请求原理 的相关文章

随机推荐