AFNetworking源码学习

简介

AFNetWorking是使用Objective-c开发iOS程序主流的网络请求开源库。

AFNetworking组织结构

AFNetWorking主要分为5个部分。NSURLSessionReachabilitysecuritySerializationUIKit。其中NSURLSession是整个网络请求开源库的灵魂,对外提供了丰富的网络请求接口。包括GETPOSTHEADPUTDELETE,与及文件上传的接口。
整个AFNetWorking组织结构如下:

源码解读

1.NSURLSession

NSURLSession包括AFURLSessionManagerAFHTTPSessionManager,AFHTTPSessionManager继承了AFURLSessionManager,对外提供了网络请求的接口。我们最常使用的GETPOST接口,底层都调用了

- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)methodURLString:(NSString *)URLStringparameters:(id)parametersuploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressdownloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgresssuccess:(void (^)(NSURLSessionDataTask *, id))successfailure:(void (^)(NSURLSessionDataTask *, NSError *))failure

整个方法的实现如下:

- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)methodURLString:(NSString *)URLStringparameters:(id)parametersuploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressdownloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgresssuccess:(void (^)(NSURLSessionDataTask *, id))successfailure:(void (^)(NSURLSessionDataTask *, NSError *))failure
{NSError *serializationError = nil;NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];if (serializationError) {if (failure) {dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{failure(nil, serializationError);});}return nil;}__block NSURLSessionDataTask *dataTask = nil;dataTask = [self dataTaskWithRequest:requestuploadProgress:uploadProgressdownloadProgress:downloadProgresscompletionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {if (error) {if (failure) {failure(dataTask, error);}} else {if (success) {success(dataTask, responseObject);}}}];return dataTask;
}

文件上传的接口例外,文件上传涉及到数据分片的问题,使用的是一个叫

- (NSURLSessionDataTask *)POST:(NSString *)URLStringparameters:(id)parametersconstructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))blockprogress:(nullable void (^)(NSProgress * _Nonnull))uploadProgresssuccess:(void (^)(NSURLSessionDataTask *task, id responseObject))successfailure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure 

接口,这个接口的全部实现如下:

- (NSURLSessionDataTask *)POST:(NSString *)URLStringparameters:(id)parametersconstructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))blockprogress:(nullable void (^)(NSProgress * _Nonnull))uploadProgresssuccess:(void (^)(NSURLSessionDataTask *task, id responseObject))successfailure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
{NSError *serializationError = nil;NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters constructingBodyWithBlock:block error:&serializationError];if (serializationError) {if (failure) {dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{failure(nil, serializationError);});}return nil;}__block NSURLSessionDataTask *task = [self uploadTaskWithStreamedRequest:request progress:uploadProgress completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {if (error) {if (failure) {failure(task, error);}} else {if (success) {success(task, responseObject);}}}];[task resume];return task;
}

AFURLSessionManager

AFURLSessionManager是整个网络请求框架的核心。
创建了url_session_manager_creation_queueurl_session_manager_processing_queue
url_session_manager_completion_group,这三个都是单例的形式。
AFURLSessionManager是以串行队列的方式进行session管理的。安全策略使用的是默认策略。

- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)requestuploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlockdownloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlockcompletionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject,  NSError * _Nullable error))completionHandler

以安全的方式,创建了一个dataTask,最后加入到mutableTask的NSMutableDictionary中。
AFURLSessionManager是AFHTTPSessionManager的基础,对AFHTTPSessionManager提供了downloadTaskuploadTaskdataTask等等的封装。

2.AFNetworkReachabilityManager

AFNetworkReachabilityManager监测网络状态。方法如下:

static AFNetworkReachabilityStatus AFNetworkReachabilityStatusForFlags(SCNetworkReachabilityFlags flags) {BOOL isReachable = ((flags & kSCNetworkReachabilityFlagsReachable) != 0);BOOL needsConnection = ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0);BOOL canConnectionAutomatically = (((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) || ((flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0));BOOL canConnectWithoutUserInteraction = (canConnectionAutomatically && (flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0);BOOL isNetworkReachable = (isReachable && (!needsConnection || canConnectWithoutUserInteraction));AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusUnknown;if (isNetworkReachable == NO) {status = AFNetworkReachabilityStatusNotReachable;}
#if    TARGET_OS_IPHONEelse if ((flags & kSCNetworkReachabilityFlagsIsWWAN) != 0) {status = AFNetworkReachabilityStatusReachableViaWWAN;}
#endifelse {status = AFNetworkReachabilityStatusReachableViaWiFi;}return status;
}

根据传入的SCNetworkReachabilityFlags标志进行判断,返回对应的网络状态。

3.AFSecurityPolicy

AFSecurityPolicy,网络请求的安全策略。该类提供了三种安全策略:

typedef NS_ENUM(NSUInteger, AFSSLPinningMode) {AFSSLPinningModeNone,AFSSLPinningModePublicKey,AFSSLPinningModeCertificate,
};

默认的安全策略是AFSSLPinningModeNone,我们可以根据需要设置对应的安全策略。
开发中实际的设置栗子如下:

- (void)setupSecurityPolicy {AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];[securityPolicy setAllowInvalidCertificates:YES];[securityPolicy setValidatesDomainName:YES];self.sessionManager.securityPolicy = securityPolicy;
}

我们当时使用的是SSL对传输的数据进行加密,来达到数据的安全传输。

4.AFURLRequestSerialization

里面是对客户端发起的请求的序列化。

- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)requestwithParameters:(id)parameterserror:(NSError *__autoreleasing *)error
{NSParameterAssert(request);NSMutableURLRequest *mutableRequest = [request mutableCopy];[self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) {if (![request valueForHTTPHeaderField:field]) {[mutableRequest setValue:value forHTTPHeaderField:field];}}];NSString *query = nil;if (parameters) {if (self.queryStringSerialization) {NSError *serializationError;query = self.queryStringSerialization(request, parameters, &serializationError);if (serializationError) {if (error) {*error = serializationError;}return nil;}} else {switch (self.queryStringSerializationStyle) {case AFHTTPRequestQueryStringDefaultStyle:query = AFQueryStringFromParameters(parameters);break;}}}if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) {if (query && query.length > 0) {mutableRequest.URL = [NSURL URLWithString:[[mutableRequest.URL absoluteString] stringByAppendingFormat:mutableRequest.URL.query ? @"&%@" : @"?%@", query]];}} else {// #2864: an empty string is a valid x-www-form-urlencoded payloadif (!query) {query = @"";}if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) {[mutableRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];}[mutableRequest setHTTPBody:[query dataUsingEncoding:self.stringEncoding]];}return mutableRequest;
}

对请求参数进行拼接,序列化,设置request的Content-Type,然后把序列化后的参数设置到HTTPBody中。
还有对应的序列化类AFJSONRequestSerializer & AFPropertyListRequestSerializer,可以把请求参数根据Content-Type序列化成application/json或者application/x-plist格式。

5.AFURLResponseSerialization

response序列化就是把响应数据使用数据解析器解析成对应的格式。AFURLResponseSerialization提供的解析器有:

  1. AFJSONResponseSerializer -> application/json/text/json/text/javascript
  2. AFXMLParserResponseSerializer -> application/xml/text/xml
  3. AFPropertyListResponseSerializer -> application/x-plist
  4. AFImageResponseSerializer -> image/jpeg/image/gif/image/png,这三种是常用的,还有其他好几种,可以到源码中查看。
  5. AFCompoundResponseSerializer 合成解析器,是上面几种的集合。

AFNetworking源码学习相关推荐

  1. AFNetworking源码学习 1

    简介: AFNetworking是iOS.macOS.watchOS和tvOS的一个令人愉快的网络库.它建立在基础URL加载系统之上,扩展了构建到Cocoa中的强大的网络高级抽象.它有一个模块化的体系 ...

  2. [iOS开发]AFNetworking源码学习

    目录 简介 开始解读 核心类 AFURLSessionManger 作用 属性和接口方法 代理 AFURLSessionManagerTaskDelegate _AFURLSessionTaskSwi ...

  3. iOS AFNetWorking源码详解(一)

    来源:Yuzeyang 链接:http://zeeyang.com/2016/02/21/AFNetWorking-one/ 首先来介绍下AFNetWorking,官方介绍如下: AFNetworki ...

  4. Shiro源码学习之二

    接上一篇 Shiro源码学习之一 3.subject.login 进入login public void login(AuthenticationToken token) throws Authent ...

  5. Shiro源码学习之一

    一.最基本的使用 1.Maven依赖 <dependency><groupId>org.apache.shiro</groupId><artifactId&g ...

  6. mutations vuex 调用_Vuex源码学习(六)action和mutation如何被调用的(前置准备篇)...

    前言 Vuex源码系列不知不觉已经到了第六篇.前置的五篇分别如下: 长篇连载:Vuex源码学习(一)功能梳理 长篇连载:Vuex源码学习(二)脉络梳理 作为一个Web前端,你知道Vuex的instal ...

  7. vue实例没有挂载到html上,vue 源码学习 - 实例挂载

    前言 在学习vue源码之前需要先了解源码目录设计(了解各个模块的功能)丶Flow语法. src ├── compiler # 把模板解析成 ast 语法树,ast 语法树优化,代码生成等功能. ├── ...

  8. 2021-03-19Tomcat源码学习--WebAppClassLoader类加载机制

    Tomcat源码学习--WebAppClassLoader类加载机制 在WebappClassLoaderBase中重写了ClassLoader的loadClass方法,在这个实现方法中我们可以一窥t ...

  9. jQuery源码学习之Callbacks

    jQuery源码学习之Callbacks jQuery的ajax.deferred通过回调实现异步,其实现核心是Callbacks. 使用方法 使用首先要先新建一个实例对象.创建时可以传入参数flag ...

最新文章

  1. yudian温控表a1温度怎么补偿_冰箱冷藏温度多少合适 冰箱冷藏温度怎么调节 看完这篇你就有答案 冰箱...
  2. 领域驱动设计门槛很高,没有深厚的面向对象编码能力很难实践成功
  3. IT技术人生路之我的大学--我技术方向的转变
  4. ExecuteNonQuery返回值问题
  5. ansible-playbook之条件判断
  6. android gridview显示本地图片大小,在Android上的GridView中调整图像大小
  7. Mac技巧之查看苹果电脑 Mac OS X 系统是否开启 64 位运算,以及设置 32/64 位模式的方法
  8. Java中加二怎么打_Java(一)(二)
  9. Bootstrap3 栅格系统之自定义mixin和变量
  10. 【英语学习】【Level 08】U03 My Choice L5 The star that shines the brightest
  11. java可以做网页吗_如果我用java 只会做网页,那么我会不会被淘汰?
  12. echarts3与echarts2区别
  13. 计算机硬盘搜索记录,怎么清除Win7搜索记录 Win7搜索历史记录删除教程
  14. zigbee终端向多个协调器发起请求的思路(终端入网流程分析)
  15. java用springboot开发的美食菜谱网(有美食达人)附论文
  16. linux设置用户的执行权限,Linux下ACL权限控制以及用sudo设置用户对命令的执行权限...
  17. 顺丰同城赴港IPO,即时配送烽火再起
  18. 玫琳凯首席创新官Lucy Gildea在2022年妇女和女童参与科学国际日的声明
  19. 互联网创业人士具备的5大素质
  20. 倩女幽魂2服务器维护怎么抢先进,玉玉倩女幽魂新区攻略-经验篇

热门文章

  1. aaynctask控制多个下载进度_做进度计划一路关卡困难重重?通关攻略了解一下!...
  2. 字节跳动高工面试:mysql索引视频教程
  3. 6阶群的非平凡子群_抽代杂谈(9): Fratinni子群和幂零群(上)
  4. java的write无法写入,Java加载ImageIO.write的文件在.jar中不起作用
  5. 锐龙r54600虚拟linux,锐龙r5 4600u相当于i几 游戏设备问题解决分享!
  6. java窗口添加标签页_在新标签页中打开新窗口
  7. Web 浏览器相关的一些概念
  8. 如何面试一位前端工程师
  9. transformer 解码_碎碎念:Transformer的解码加速
  10. 质性研究工具_MAXQDA在质性数据分析中的使用——免费的中文在线研讨会!