AFN的使用與思考(每次對(duì)接后臺(tái)接口都是一段痛苦旅程)

最近牵舵,一個(gè)同事打算離職柒啤,聊到技術(shù)上倦挂,就順便說道一個(gè)話題:
AFN的底層原理你知道嗎?

恰好担巩,最近正好處于三個(gè)項(xiàng)目交接期方援、起步期,跟不同的后臺(tái)開發(fā)人員和接口約定打了交道涛癌,發(fā)現(xiàn)問題(坑犯戏,后臺(tái)開發(fā)不規(guī)范導(dǎo)致)還是很多的。

要講清這個(gè)問題拳话,首頁得了解1.AFN怎么請(qǐng)求的先匪?2.一個(gè)網(wǎng)絡(luò)請(qǐng)求是怎么構(gòu)成的?為什么我的網(wǎng)絡(luò)請(qǐng)求失敗,別人能成功呢弃衍?
1.關(guān)于問題一呀非,文章http://www.reibang.com/p/96f115bcd913里講解的很清楚

2.關(guān)于問題二,我們需要看一下這個(gè)[AFHTTPSessionManager manager] 里面有什么镜盯!

@property (readonly, nonatomic, strong, nullable) NSURL *baseURL;
@property (nonatomic, strong) AFHTTPRequestSerializer <AFURLRequestSerialization> * requestSerializer;
@property (nonatomic, strong) AFHTTPResponseSerializer <AFURLResponseSerialization> * responseSerializer;
我將它們定位一個(gè)網(wǎng)絡(luò)請(qǐng)求的三要素
基本的URL岸裙,請(qǐng)求序列化器,響應(yīng)序列化器

我們重點(diǎn)看:這個(gè)三個(gè)要素怎么生成一個(gè)request的對(duì)象的速缆!

如果你只會(huì)上面那個(gè)文章里面調(diào)用請(qǐng)求降允,那你一定還處于AFN的入門使用階段。
如果你還會(huì)配置時(shí)間艺糜、緩存等參數(shù)剧董,那你進(jìn)入了初級(jí)階段。
如果你知道倦踢,一個(gè)get請(qǐng)求與post請(qǐng)求在AFN里面怎么拼裝送滞,怎么生效的原理,那么恭喜你進(jìn)入中級(jí)階段辱挥,我也才剛剛悟道犁嗅,分享一下。

要素一:url
如果是get請(qǐng)求晤碘,那么生成request可能是這樣的
https://host/v4/store/searchAppList?jsonObj={"platform":"android","userName":"fengj","appId":"qweasdzxc"}
PS:注意褂微?= 這個(gè)兩種符號(hào)是帶出了參數(shù)。
參數(shù)體現(xiàn)在url里面园爷。
那么在生成最終的請(qǐng)求類型request時(shí)宠蚂,一定要看后面的參數(shù)樣式,因?yàn)闃邮讲粚?duì)就會(huì)導(dǎo)致請(qǐng)求失敗童社。
如下列這種get請(qǐng)求肯定失斍蟛蕖:
https://host/v4/store/searchAppList?=%7B%20%20%22jsonObj%22%20%3A%20%7B%20%20%20%20%22appId%22%20%3A%20%22qweasdzxc%22%2C%20%20%20%20%22platform%22%20%3A%20%22iphone%22%2C%20%20%20%20%22userName%22%20%3A%20%22fengj%22%20%20%7D%7D
(這里是AFN默認(rèn)使用了urlcode 也就是escape編碼了)
https://host/v4/store/searchAppList?={jsonObj:{"appId":"qweasdzxc","platform":"iphone","userName":"fengj"}
或者這種請(qǐng)求也是不對(duì)的
https://host/v4/store/searchAppList?jsonObj[BappId]=qweasdzxc&jsonObj[platform]=iphone&jsonObj[userName]=fengj

為什么會(huì)產(chǎn)生這種get類型的URL呢?
關(guān)鍵代碼在AFURLRequestSerialization.m 中這個(gè)方法(466行)中:

  • (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request
    withParameters:(id)parameters
    error:(NSError *__autoreleasing *)error{
    ....
    }
    這個(gè)方法里面針對(duì)get請(qǐng)求進(jìn)行了url參數(shù)的拼接,和針對(duì)post請(qǐng)求的body中的Data數(shù)據(jù)進(jìn)行了處理呀癣,還有很關(guān)鍵的HTTPRequestHeaders 請(qǐng)求頭的配置美浦。
    具體自己可以讀一下代碼。
    這里告知一下我犯錯(cuò)誤的原因:參數(shù)parameters 不符合后臺(tái)的需求项栏,自然接口不通浦辨!
    如: NSDictionary * dic = @{
    @"appId":@"qweasdzxc",
    @"userName":@"fengj",
    @"platform":@"iphone",
    };
    NSString * jsonString = [NSDictionary convertToJSONData:dic];
    requestArgumentDic = @{@"jsonObj":[jsonString description]
    }.mutableCopy;

與 requestArgumentDic = @{@"jsonObj":@{
@"appId":@"qweasdzxc",
@"userName":@"fengj",
@"platform":@"iphone",
}
}.mutableCopy;
這兩種參數(shù)類型就是截然不同的:
在iOS的世界:一個(gè)是字典,key對(duì)應(yīng)的是jsonStr沼沈;另一個(gè)是字典套字典
在java開發(fā)(安卓與后臺(tái))的世界:第一個(gè)是一個(gè)key-object 健值-對(duì)象模型流酬,另一個(gè)就是Map形式純嵌套。
因?yàn)楹笈_(tái)的解開數(shù)據(jù)方式不一樣列另,會(huì)導(dǎo)致后臺(tái)不認(rèn)識(shí)你傳過來的數(shù)據(jù)

要素二: 上述要素一種牽扯的方法芽腾,其實(shí)就是requestSerializer的方法
他們是協(xié)議關(guān)系,具體關(guān)系访递,可以看這篇文章:http://www.reibang.com/p/96f115bcd913 介紹地很詳細(xì)晦嵌。

如這篇文章所說,上面這個(gè)方法拷姿,更多是處理request的參數(shù)序列化問題惭载。

仔細(xì)讀這個(gè)方法:
可以知道一個(gè)mutableRequest 有三個(gè)重要組成部分
1、HTTPRequestHeaders
2响巢、url
3描滔、parameters (get時(shí)是url的后綴,post 是HTTPBody中的NSData數(shù)據(jù))

如果這三個(gè)要素完全一致踪古,不可能出現(xiàn)安卓接口調(diào)通含长,而iOS不通的情況的。

我遇到的畸形案列:
某一后臺(tái)要的數(shù)據(jù)(post body中的數(shù)據(jù)):沒有進(jìn)行urlcode編碼(一般情況下:URl中參數(shù)有沒有urlcode編碼都能請(qǐng)求通過伏穆,而nsdata中數(shù)據(jù)不一樣拘泞,后臺(tái)拿到數(shù)據(jù)解析方式?jīng)Q定能否使用。)但是AFN框架默認(rèn)會(huì)進(jìn)行urlcode編碼(文件名:AFURLRequestSerialization.m枕扫,方法名:AFQueryStringFromParameters(NSDictionary *parameters)里面122行[pair URLEncodedStringValue])陪腌;
對(duì)應(yīng)解決方法如下:

    AFHTTPRequestSerializer * requestSerializer = [AFHTTPRequestSerializer serializer];
    [manager setRequestSerializer:requestSerializer];
    [requestSerializer setQueryStringSerializationWithBlock:^NSString * _Nonnull(NSURLRequest * _Nonnull request, id  _Nonnull parameters, NSError * _Nullable __autoreleasing * _Nullable error) {
        return [NSDictionary convertToJSONData:parameters];
    }];

手動(dòng)設(shè)置requestSerializer參數(shù)query的字符串模式

第二個(gè)犯錯(cuò)的案列 比較簡(jiǎn)單
HTTPRequestHeaders 必須設(shè)置對(duì),尤其是這兩個(gè)參數(shù) Content-Type 與Accept
1.請(qǐng)求參數(shù)的格式 (另一種格式application/x-www-form-urlencoded;charset=UTF-8 )
[requestSerializer setValue:@"application/json;charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
2.返回參數(shù)的格式
[requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Accept"];

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末烟瞧,一起剝皮案震驚了整個(gè)濱河市诗鸭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌参滴,老刑警劉巖强岸,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異砾赔,居然都是意外死亡蝌箍,警方通過查閱死者的電腦和手機(jī)青灼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來十绑,“玉大人聚至,你說我怎么就攤上這事”境龋” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵脆诉,是天一觀的道長(zhǎng)甚亭。 經(jīng)常有香客問我,道長(zhǎng)击胜,這世上最難降的妖魔是什么亏狰? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮偶摔,結(jié)果婚禮上暇唾,老公的妹妹穿的比我還像新娘。我一直安慰自己辰斋,他們只是感情好策州,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著宫仗,像睡著了一般够挂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上藕夫,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天孽糖,我揣著相機(jī)與錄音,去河邊找鬼毅贮。 笑死办悟,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的滩褥。 我是一名探鬼主播病蛉,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼铸题!你這毒婦竟也來了铡恕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤丢间,失蹤者是張志新(化名)和其女友劉穎探熔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體烘挫,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡诀艰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年柬甥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片其垄。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡苛蒲,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出绿满,到底是詐尸還是另有隱情臂外,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布喇颁,位于F島的核電站漏健,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏橘霎。R本人自食惡果不足惜蔫浆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望姐叁。 院中可真熱鬧瓦盛,春花似錦、人聲如沸外潜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽橡卤。三九已至扮念,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間碧库,已是汗流浹背柜与。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嵌灰,地道東北人弄匕。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像沽瞭,于是被迫代替她去往敵國(guó)和親迁匠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容