美文网首页
AFNetworking

AFNetworking

作者: _既白_ | 来源:发表于2019-05-05 20:53 被阅读0次
    656644-c84285077d0bc2dd-2.png

    AFNetworking 主要组成

    AFNetworking

    除去Support Files,可以看到AF分为如下5个功能模块:

    NSURLSession : 网络通信模块,包含AFURLSessionManagerAFHTTPSessionManger
    Reachability : 网络状态监听模块,包含AFNetworkReachabilityManage
    Security : 网络通信安全策略模块,包含 AFSecurityPolicy
    Serialization : 网络通信信息序列化/反序列化模块,包括AFURLRequestSerializationAFURLResponesSerialization
    UIKit : 对于iOS UIKit库的扩展

    其核心当然是网络通信模块NSURLSessionManager。大家都知道,AF3.x是基于NSURLSession来封装的。所以这个类围绕着NSURLSession做了一系列的封装。而其余的四个模块,均是为了配合网络通信或对已有UIKit的一个扩展工具包。

    AFNetworking请求流程分析

    // 简单的get 请求
    AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]init];
    
    [manager GET:@"http://localhost" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    
    }];
    

    初始化AFHTTPSessionManager 对象

    //  AFHTTPSessionManager相关的初始化方法
    + (instancetype)manager {
        return [[[self class] alloc] initWithBaseURL:nil];
    }
    
    - (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
    {
    
    // 调用父类AFURLSessionManage 的初始化方法 initWithSessionConfiguration:
        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;
    }
    

    初始化最终都 - (instancetype)initWithBaseURL:(NSURL *)url sessionConfiguration:(NSURLSessionConfiguration *)configuration方法,
    其实初始化方法都调用父类(AFURLSessionManager)的初始化方法
    除此之外,方法中把baseURL存了起来,还生成了一个请求序列对象和一个响应序列对象。

    直接来到父类AFURLSessionManager的初始化方法:

    
    - (instancetype)init {
        return [self initWithSessionConfiguration:nil];
    }
    
    - (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration {
        self = [super init];
        if (!self) {
            return nil;
        }
    
    // (1)初始化会话配置(session configuration),默认为defaultSessionConfiguration
        if (!configuration) {
            configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
        }
        self.sessionConfiguration = configuration;
      
    // (2)初始化队列,设置队列的最大并发数
        self.operationQueue = [[NSOperationQueue alloc] init];
        //queue并发线程数设置为1
        self.operationQueue.maxConcurrentOperationCount = 1;
    
      (3)初始化会话(session),并将session的代理对象设置为self(也就是当前AFURLSessionManager对象),并将代理队列设置为(2)中创建的队列。
        self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];
    
        //各种响应转码
        self.responseSerializer = [AFJSONResponseSerializer serializer];
    
        //设置默认安全策略
        self.securityPolicy = [AFSecurityPolicy defaultPolicy];
    
    #if !TARGET_OS_WATCH
        self.reachabilityManager = [AFNetworkReachabilityManager sharedManager];
    #endif
        // 设置存储NSURL task与AFURLSessionManagerTaskDelegate的词典(重点,在AFNet中,每一个task都会被匹配一个AFURLSessionManagerTaskDelegate 来做task的delegate事件处理) ===============
        self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init];
    
        //  设置AFURLSessionManagerTaskDelegate 词典的锁,确保词典在多线程访问时的线程安全
        self.lock = [[NSLock alloc] init];
        self.lock.name = AFURLSessionManagerLockName;
    
        // 置空task关联的代理
        [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;
    }
    
    

    在该初始化方法中,它做了这么几件事:
    (1)初始化会话配置(session configuration),默认为defaultSessionConfiguration
    (2)初始化队列,设置队列的最大并发数
    (3)初始化会话(session),并将session的代理对象设置为self(也就是当前AFURLSessionManager对象),并将代理队列设置为(2)中创建的队列。
    (4)初始化响应序列化
    (5)初始化安全认证
    (6)初始化网络状态监控
    (7)初始化保存NSURLSessionDataTaskAFURLSessionManagerTaskDelegate的字典
    (8)初始化线程锁
    (9)为已经存在的task设置delegate,置空task关联的代理

    // AFHTTPSessionManager 中 get 方法
    - (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
    {
         //生成一个task
        NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET"
                                                            URLString:URLString
                                                           parameters:parameters
                                                       uploadProgress:nil
                                                     downloadProgress:downloadProgress
                                                              success:success
                                                              failure:failure];
    
        //开始网络请求
        [dataTask resume];
    
        return dataTask;
    }
    
    

    方法走到类AFHTTPSessionManager中来,调用父类,也就是我们整个AF3.x的核心类AFURLSessionManager的方法,生成了一个系统的NSURLSessionDataTask实例,并且开始网络请求。
    我们继续往父类里看,看看这个方法到底做了什么:

    AFHTTPSessionManager 
    - (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;
    
        //把参数,还有各种东西转化为一个request
        NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];
    
        if (serializationError) {
            if (failure) {
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Wgnu"
                //如果解析错误,直接返回
                dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
                    failure(nil, serializationError);
                });
    #pragma clang diagnostic pop
            }
    
            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;
    }
    
    

    这个方法做了两件事:

    • 用self.requestSerializer和各种参数去获取了NSMutableURLRequest请求实例
    • 调用另外一个方法dataTaskWithRequest去拿到我们最终需要的NSURLSessionDataTask实例,并且在完成的回调里,调用我们传过来的成功和失败的回调

    说到底AFHTTPSessionManager 中 这个方法还是没有做实事,我们继续到requestSerializer方法里去看,看看AF到底如何拼接成我们需要的request的:
    接着我们跑到AFURLRequestSerialization类中:

    // AFURLRequestSerialization
    - (NSMutableURLRequest *)requestWithMethod:(NSString *)method
                                     URLString:(NSString *)URLString
                                    parameters:(id)parameters
                                         error:(NSError *__autoreleasing *)error
    {
        //断言,debug模式下,如果缺少改参数,crash
        NSParameterAssert(method);
        NSParameterAssert(URLString);
    
        NSURL *url = [NSURL URLWithString:URLString];
    
        NSParameterAssert(url);
    
        NSMutableURLRequest *mutableRequest = [[NSMutableURLRequest alloc] initWithURL:url];
        mutableRequest.HTTPMethod = method;
    
        //将request的各种属性循环遍历
        for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) {
            //如果自己观察到的发生变化的属性,在这些方法里
            if ([self.mutableObservedChangedKeyPaths containsObject:keyPath]) {
               //把给自己设置的属性给request设置
                [mutableRequest setValue:[self valueForKeyPath:keyPath] forKey:keyPath];
            }
        }
        //将传入的parameters进行编码,并添加到request中
        mutableRequest = [[self requestBySerializingRequest:mutableRequest withParameters:parameters error:error] mutableCopy];
    
        return mutableRequest;
    }
    
    

    相关文章

      网友评论

          本文标题:AFNetworking

          本文链接:https://www.haomeiwen.com/subject/gqylnqtx.html