AFN源码解析 | 第一天

Demo地址

github.com/tanghaitao/…

AFN大体框架

image.png

总的思路

url — request (configureation)– task — session — 代理 — manager — client — 模块网络(RAC)

本章主要分析 NSURLSession部分

本章对应Demo地址:

github.com/tanghaitao/…

NSURLSession流程

image.png

@interface AFHTTPSessionManager : AFURLSessionManager <NSSecureCoding, NSCopying>

AFHTTPSessionManager主要构成

Get Post等请求
image.png

AFURLSessionManager主要构成

代理请求,回调等任务执行过程

image.png

//这里只是初始化,并不是单例,
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
return [[[self class] alloc] initWithBaseURL:nil];
复制代码

通过configuration 初始化 NSURLSession

调用父类初始化方法,
self = [super initWithSessionConfiguration:configuration];

/*
 1.初始化一个session
 2.给manager的属性设置初始值
 */
- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration {
    self = [super init];
    if (!self) {
        return nil;
    }

    //设置默认的configuration,配置我们的session
    if (!configuration) {
        configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    }

    //持有configuration
    self.sessionConfiguration = configuration;

    // 创建session 串行 : 多个task, 回调是异步的
    //设置为delegate的操作队列并发的线程数量1,也就是串行队列
    self.operationQueue = [[NSOperationQueue alloc] init];
    self.operationQueue.maxConcurrentOperationCount = 1;
    
    // block 粗糙 数据 :只会返回response,data,error
    // delegate : block, 状态码(cancel),进度条等所有的数据。

    /*
     -如果完成后需要做复杂(耗时)的处理,可以选择异步队列
     -如果完成后直接更新UI,可以选择主队列
     [NSOperationQueue mainQueue]
     */
    
    self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];

    //默认为json解析
    self.responseSerializer = [AFJSONResponseSerializer serializer];

    //设置默认证书 无条件信任证书https认证
    self.securityPolicy = [AFSecurityPolicy defaultPolicy];

#if !TARGET_OS_WATCH
    //网络状态监听
    self.reachabilityManager = [AFNetworkReachabilityManager sharedManager];
#endif

    // 为什么要收集: cancel resume supend : task : id
    //delegate= value taskid = key
    self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init];

    //使用NSLock确保线程安全
    self.lock = [[NSLock alloc] init];
    self.lock.name = AFURLSessionManagerLockName;

    
    //异步的获取当前session的所有未完成的task。其实讲道理来说在初始化中调用这个方法应该里面一个task都不会有
    //后台任务重新回来初始化session,可能就会有先前的任务
    //https://github.com/AFNetworking/AFNetworking/issues/3499
    //
    
    [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
        for (NSURLSessionDataTask *task in dataTasks) {
            [self addDelegateForDataTask:task uploadProgress:nil downloadProgress:nil completionHandler:nil];
        }

        for (NSURLSessionUploadTask *uploadTask in uploadTasks) {
            [self addDelegateForUploadTask:uploadTask progress:nil completionHandler:nil];
        }

        for (NSURLSessionDownloadTask *downloadTask in downloadTasks) {
            [self addDelegateForDownloadTask:downloadTask progress:nil destination:nil completionHandler:nil];
        }
    }];

    return self;
}
复制代码

HTTPS的流程图和详细分析

image.png

  1. 客户端发送请求url,这个url是基于https的,https相当于http+ssl加密策略
  2. 服务端验证这边有 公钥和 私钥
  3. 服务端通过 公钥 设置加密算法 响应给客户端
  4. 客户端将 接收到的crt本地的crt进行比对(本地,后台提供的ca证书),验证通过后生成一个随机数random key 放到 公钥 中加密保存
  5. 将这个 加密的公钥 发送给 服务端
  6. 服务端通过 私钥 解开 加密的公钥,获得 客户端的 随机数random key,通过这个key 加密 所有要传递的数据,比如response, name,token等
  7. 将这些数据发送给客户端
  8. 客户端通过 随机数random key 解密

这就是https的整个流程。

请求参数处理

- (NSURLSessionDataTask *)GET:(NSString *)URLString
                   parameters:(id)parameters
                     progress:(void (^)(NSProgress * _Nonnull))downloadProgress
                      success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
                      failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
{

    // http: 请求行 + 请求头 + 请求体
    // 多线程 task ?
    //返回一个task,然后开始网络请求
    NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET"
                                                        URLString:URLString
                                                       parameters:parameters
                                                   uploadProgress:nil
                                                 downloadProgress:downloadProgress
                                                          success:success
                                                          failure:failure];

    //开始网络请求
    [dataTask resume];

    return dataTask;
}
复制代码
//1.生成request,2.通过request成成task
- (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
{
    NSError *serializationError = nil;
    /*
     1.先调用AFHTTPRequestSerializer的requestWithMethod函数构建request
     2.处理request构建产生的错误 – serializationError
     //relativeToURL表示将URLString拼接到baseURL后面

     */
    NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];
    
复制代码

[self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError]

附上 Xcode配置Python环境:
blog.csdn.net/qq_15289761…

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享