Files
knowledge-kit/Chapter1 - iOS/1.138.md
2024-07-15 20:03:01 +08:00

132 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AFNetworking 源码解读
## 结构
核心包含5个功能模块
- 网络通信模块(AFURLSessionManager、AFHTTPSessionManger)
- 网络状态监听模块(Reachability)
- 网络通信安全策略模块(Security)
- 网络通信信息序列化/反序列化模块(Serialization)
- 对于iOS UIKit库的扩展(UIKit)
AF 是基于 NSURLSession 来封装的,所以核心类 AFURLSessionManager 也是针对 NSURLSession 做的封装其余的4个模块是为了网络通信请求、响应数据的序列化、HTTPS 安全认证、UIKit 推展)
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/AFNetworkingProcess.png" style="zoom:60%" />
其中 AFHTTPSessionManager 继承自 AFURLSessionManager一般的网络请求都是用这个类但是该类本身没有处理实际的网络而是做了一些封装把请求逻辑分发给父类 AFURLSessionManager 或者其他类去做。
## 以 get 请求为例
```objective-c
AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]init];
[manager GET:@"https://somehost.com/goods" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}];
```
调用初始化方法生成一个 manager去看看具体做了什么
```objective-c
- (instancetype)init {
return [self initWithBaseURL:nil];
}
- (instancetype)initWithBaseURL:(NSURL *)url {
return [self initWithBaseURL:url sessionConfiguration:nil];
}
- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration {
return [self initWithBaseURL:nil sessionConfiguration:configuration];
}
- (instancetype)initWithBaseURL:(NSURL *)url
sessionConfiguration:(NSURLSessionConfiguration *)configuration
{
self = [super initWithSessionConfiguration:configuration];
if (!self) {
return nil;
}
// 对传过来的 BaseUrl 进行处理,如果有值且最后不包含/url加上"/"
if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"/"]) {
url = [url URLByAppendingPathComponent:@""];
}
self.baseURL = url;
self.requestSerializer = [AFHTTPRequestSerializer serializer];
self.responseSerializer = [AFJSONResponseSerializer serializer];
return self;
}
```
初始化都调用到
## 数字证书
数字签名,它能确认消息的完整性,进行认证。
和公钥密码一样也要用到一对公钥、私钥。但相反的是,签名是用私钥加密(生成签名),公钥解密(验证签名)。私钥加密只能有吃有私钥的人完成,而由于公钥是对外公开的,因此任何人都可以用公钥解密(验证签名)。
<img src="https://raw.githubusercontent.com/FantasticLBP/knowledge-kit/master/assets/DataSignProcess.png" style="zoom:30%" />
公钥基础设置PKI是为了能够更有效地运用公钥而制定的一系列规范和规格的总称使用最广泛的 X.509 规范也是 PKI 的一种。
### 证书链
CA 有层级关系,处于最顶层的认证机构一般是根 CA下面证书是经过上层签名的而根 CA 则会对自己的证书进行签名。即自签名。
怎么验证证书有没有被篡改?
当客户端走 HTTPS 访问站点时服务器会返回整个证书链。先从最底层的CA开始用上层的公钥对下层证书的数字签名进行验证。这样逐层向上验证直到遇到了锚点证书。
## 以 get 请求为例,展开探索
1. 请求入口
```
- (NSURLSessionDataTask *)GET:(NSString *)URLString
parameters:(id)parameters
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
```
2. 创建 NSURLSessionDataTask
```
- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(id)parameters
uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgress
downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress
success:(void (^)(NSURLSessionDataTask *, id))success
failure:(void (^)(NSURLSessionDataTask *, NSError *))failure
```
## 较原生相比AF 做了什么事情
拿 get、post 为入口,分析源码
- 初始化很多属性
- 安全措施iOS 8 TaskID 不唯一的问题。dispatch_sync
- 自定义了一个 block 进度回调,使用起来更加方便
- 用到了解耦,降低了主类的复杂度,维护起来更加方便
## AFSecurityPolicy 源码分析 HTTPS 认证
https://www.jianshu.com/p/856f0e26279d
https://www.jianshu.com/u/14431e509ae8
https://blog.csdn.net/ZCMUCZX/article/details/79399517