# AFNetworking 源码解读 ## 结构 核心包含5个功能模块: - 网络通信模块(AFURLSessionManager、AFHTTPSessionManger) - 网络状态监听模块(Reachability) - 网络通信安全策略模块(Security) - 网络通信信息序列化/反序列化模块(Serialization) - 对于iOS UIKit库的扩展(UIKit) AF 是基于 NSURLSession 来封装的,所以核心类 AFURLSessionManager 也是针对 NSURLSession 做的封装,其余的4个模块,是为了网络通信(请求、响应数据的序列化、HTTPS 安全认证、UIKit 推展) 其中 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; } ``` 初始化都调用到 ## 数字证书 数字签名,它能确认消息的完整性,进行认证。 和公钥密码一样也要用到一对公钥、私钥。但相反的是,签名是用私钥加密(生成签名),公钥解密(验证签名)。私钥加密只能有吃有私钥的人完成,而由于公钥是对外公开的,因此任何人都可以用公钥解密(验证签名)。 公钥基础设置(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