AFNetworking源码阅读笔记(二)

二、Serialization的AFURLRequestSerialization部分

AFHTTPRequestSerializer是序列化器,主要功能是对传入的参数进行序列化。

在前一篇分析过,

其主要是通过构造request来实现其功能的,这里也将从这个入口开始,分析requestSerializer是如何构造这个NSMutableURLRequest  *request对象的。

在此之前先来看一下AFHTTPRequestSerializer的初始化方法:


表示返回一个默认配置的序列化器。

self.stringEncoding为编码方式,如果不做特别设置默认是UTF8。

self.mutableHTTPRequestHeaders为请求头构建的字典,self.requestHeaderModificationQueueself.mutableHTTPRequestHeaders的操作队列。

可以看得出对请求头字典的操作都在self.requestHeaderModificationQueue这个并发队列中进行。在获取请求头字典或是获取其中一个值时,

都使用同步添加任务

插入或移除条目时,

都使用了dispatch_barrier_async异步栅栏添加任务

[NSLocale  preferredLanguages]获取当前使用语言,参见详情1参见详情2

这块就是向请求头中插入Accept-Language字段。

插入User-Agent字段,主要包含一些设备信息。

通过KVO添加对属性的观察,继续深入这个AFHTTPRequestSerializerObservedKeyPaths()函数:

可以看出是对着五个属性添加了属性观察,以timeoutInterval为例:

需要手动实现属性的 setter 方法,在设置操作的前后分别调用 willChangeValueForKey: 和 didChangeValueForKey方法,这两个方法用于通知系统该 key 的属性值即将和已经变更了;

下面开始具体分析这个request的构造方法:


系统方法创建NSMutableURLRequest *mutableRequest,并赋值urlHTTPMethod

存储观察属性的相关值。

下面重点分析这个方法:

self.HTTPRequestHeaders的值赋给request,所以如果在发送请求时要设置或添加请求头信息,都可通过self.HTTPRequestHeaders来完成。

下面就是最重要一部分编码过程:

分析AFURLRequestSerialization默认编码过程:

再继续深入AFQueryStringPairsFromDictionary(parameters)这个方法:

下面可知AFQueryStringPairsFromDictionary方法只接受NSDictionary*类型参数列表。

构造一个空的数组以供后面使用,构造一个排序器,看的出是针对排序集合元素的description属性进行排序。

下面就是NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value)这个函数的核心部分,以参数为字典为例:

先对dictionaryallKeys按之前构造的排序器排序[dictionary.allKeys sortedArrayUsingDescriptors:@[sortDescriptor]],然后对排完序的数组进行遍历for(id nestedKey in [dictionary.allKeys sortedArrayUsingDescriptors:@[sortDescriptor]]) {

在遍历过程中每一步中递归调用[mutableQueryStringComponents addObjectsFromArray:AFQueryStringPairsFromKeyAndValue((key ? [NSStringstringWithFormat:@"%@[%@]", key, nestedKey] : nestedKey), nestedValue)]。具体分析这个方法:nestedKeydictionary每个条目的key值,nestedValue为每个条目的value值,可知在第一次调这个方法时

传入的keynil,所以在递归调用这个方法时传入的key即为nestedKey,传入的value即为nestedValue,假设nestedValue不为字典、数组、集合对象,则走入

具体看一下AFQueryStringPair这个类及相关方法。

可知是一个参数条目的对象,pair表示是成对出现的fieldvalue组成的对象,这也符合一般情况下的网络请求参数格式。然后再加入方法起始时构造的mutableQueryStringComponents的数组中,当传进来的参数列表遍历结束后,返回一个由AFQueryStringPair*类型对象组成的数组。

这里是以一个常见格式的字典类型参数为例,其他参数列表类型同样。

接着返回到

这个方法里边,可看出

在这里对上一步返回的AFQueryStringPair*类型对象数组进行遍历,每一个对象调用[pair URLEncodedStringValue]编码方法。

可看出编码的核心方法是NSString * AFPercentEscapedStringFromString(NSString *string)

这个方法前源码中有一段注释文档

可参考这里

具体分析:

构造一个字符集allowedCharacterSet,除去kAFCharactersGeneralDelimitersToEncodekAFCharactersSubDelimitersToEncode包含的字符,allowedCharacterSet中为字符中允许的字符,否则要转译。

这块是对传入的参数string进行相关的UTF-8编码

allowedCharacterSet表示在编码中可以保留的字符,否则要转译。

参看详情

现在返回到

可知[pair URLEncodedStringValue]是对每一个AFQueryStringPair*类型pair对象进行编码,再回到这里

可知query = AFQueryStringFromParameters(parameters)方法便可得到相应的编码后的字符串,回到这里

继续往下走

之前不知道self.HTTPMethodsEncodingParametersInURI这是干啥的,到这里明白了,看看之前的代码

可看出,如果请求使用get方式则走到这里

设置mutableRequestURL值。

如果请求方式为post,则走到这里

意思是如果请求头没设置Content-Type,默认是application/x-www-form-urlencoded表单提交,然后[mutableRequest setHTTPBody:[querydataUsingEncoding:self.stringEncoding]]设置post请求的body体。

最终返回mutableRequest

最后返回到这个方法

一个NSMutableURLRequest *类型的request对象构造完成,可以提供给上篇文章的NSDataTask用以构造dataTask请求任务对象。

接下来简析一下AFURLRequestSerialization的整体面貌:

可看出这篇文章所着重分析的request对象构造方法是@protocol  AFURLRequestSerialization协议的方法。从AFURLRequestSerialization.h头文件可看出框架实现的序列化器有三种

AFHTTPRequestSerializer是最基础的类型遵守了AFURLRequestSerialization协议,AFJSONRequestSerializer用于json提交时使用,AFPropertyListRequestSerializer用于application/x-plist提交时使用,它们都单独实现了- (nullable NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request withParameters:(nullableid)parameters error:(NSError*_Nullable__autoreleasing*)error方法。本文主要分析的是AFHTTPRequestSerializer的实现方法,其他两种不再赘述。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容