很多時候状共,AFNetworking都是目前iOS開發(fā)者網(wǎng)絡(luò)庫中的不二選擇丽焊。Github上2W+的star數(shù)足見其流行程度余耽。而從iOS7.0開始戴而,蘋果推出了新的網(wǎng)絡(luò)庫繼承者NSURLSession后,AFNetworking也毫不猶豫地加入了對其的支持挽霉。3.0+更加只是提供了NSURLSession的支持防嗡。
我們使用AFNetworking的時候,可能會有很多的朋友都會采用以下的寫法:
AFHTTPSessionManager *sessionManager = [AFHTTPSessionManager manager];
sessionManager.requestSerializer = [AFHTTPRequestSerializer serializer];
sessionManager.responseSerializer = [AFHTTPResponseSerializer serializer];
[sessionManager GET:urlString
parameters:parameters
progress:progressBlock
success:successHandler
failure:failureHandler];
大概可以描述一下這個過程侠坎,每次開啟一個網(wǎng)絡(luò)請求時蚁趁,首先新建一個AFHTTPSessionManager,然后將相關(guān)的requestSerializer和reponseSerializer賦值实胸;最后發(fā)起相應(yīng)的GET/POST等請求他嫡。
而如果是直接采用NSURLSession來請求網(wǎng)絡(luò)呢,我們則經(jīng)常會采用以下的寫法:
NSURLSession *session = [NSURLSession
sessionWithConfiguration:
[NSURLSessionConfiguration defaultSessionConfiguration]
delegate:nil
delegateQueue:[NSOperationQueue mainQueue]];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:completionHandler];
[dataTask resume];
這個過程其實和上面的基本一致童芹。新建一個Session涮瞻,然后新建task,激活task假褪,完成網(wǎng)絡(luò)請求署咽。
那么現(xiàn)在問題來了。為什么每次都需要新建一個SessionManager/Session生音?如果在多個Task請求的情況下宁否,如果采取一個共享的SessionManager/Session是否可行?如果可行缀遍,與之前每次新建SessionManager/Session相比慕匠,孰優(yōu)孰劣?
本篇文章會告訴您:
- 為什么要使用NSURLSession而不是NSURLConnection
- 為什么要用共享的SessionManager/Session域醇,而不是每次都啟動一個新的
為什么要選擇NSURLSession
NSURLSession在iOS7.0時被Apple提出后台谊,雖然Apple一直對其良好的API設(shè)計大力推廣蓉媳,然而其能夠達(dá)到的效果,似乎一直都和NSURLConnection不相伯仲锅铅。
特別是在網(wǎng)絡(luò)的Dependecy依賴處理上酪呻,由于AFNetworking優(yōu)秀的架構(gòu)設(shè)計,NSURLSession甚至還不如NSURLConnection好用盐须。那么玩荠,有什么理由切換到NSURLSession? 2015年的WWDC似乎告訴了我們答案贼邓。
HTTP /2, 2015年5月RFC 7540正式發(fā)表的下一代HTTP協(xié)議阶冈,是1999年來HTTP 1.1發(fā)布后的首個更新。相對于前一個版本塑径,HTTP /2以快著稱女坑。如下圖,對相同圖片统舀、相同服務(wù)器的下載堂飞,在不同協(xié)議下所需的時間:
http2
這里我們并不打算展開HTTP /2的原理,有興趣的同學(xué)可以Google之绑咱。根據(jù)2015的WWDC Session711,我們知道iOS9+枢泰,NSURLSession開始正式支持HTTP /2描融,也就意味著你的網(wǎng)絡(luò)連接速度也可以有如上圖那樣的提升。
更人性化更優(yōu)秀的API設(shè)計衡蚂,HTTP /2的支持窿克,這是否能成為你使用NSURLSession的理由?至少它們成為了說服我的理由毛甲。
為什么要盡量共享Session年叮,而不是每次新建Session
在回答這個問題以前,我們先來聊聊網(wǎng)絡(luò)的通訊協(xié)議玻募。我們也都知道只损,HTTP協(xié)議是基于TCP協(xié)議的。所以在每次的HTTP請求之前七咧,客戶端和服務(wù)器端跃惫,都先需要經(jīng)過TCP連接的三次握手,即每次請求之前艾栋,網(wǎng)絡(luò)的數(shù)據(jù)都已經(jīng)在客戶端和服務(wù)器端之間來回了三次爆存。如下圖:
TCP三次握手(圖片來源于網(wǎng)絡(luò))
事實上在HTTP 0.9, HTTP 1.0協(xié)議的時代,每次HTTP的請求蝗砾,都需要先經(jīng)過TCP的連接先较,然后才開始HTTP的請求携冤,這樣一個流程圖,我們可以通過抓包看到:
抓包
那么闲勺,為了讓我們的請求更快曾棕,避免每次都產(chǎn)生一個TCP三次握手,成了一個優(yōu)化的選項霉翔。于是在HTTP 1.1中睁蕾,出現(xiàn)了Connection: keep-alive這個選項。這個優(yōu)化選項债朵,可以使得客戶端和服務(wù)器端復(fù)用一個TCP連接子眶,從而減小每次的網(wǎng)絡(luò)請求時間。
聊到這里序芦,本章提出的問題臭杰,其實答案已經(jīng)逐漸明了了。沒錯谚中,共享的Session將會復(fù)用TCP的連接渴杆,而每次都新建Session的操作將導(dǎo)致每次的網(wǎng)絡(luò)請求都開啟一個TCP的三次握手。
從上面兩張圖宪塔,我們可以清晰地看到磁奖,同樣都是兩次HTTP請求,共享Session的代碼在第二次網(wǎng)絡(luò)請求時少了TCP的三次握手的過程某筐。即加速了整個網(wǎng)絡(luò)的請求時間比搭。
事實上,蘋果的文檔中南誊,還對一個服務(wù)器最高的TCP并發(fā)有相應(yīng)的描述:
HTTPMaximumConnectionsPerHost Property
The maximum number of simultaneous connections to make to a given host.
Declaration
SWIFT
var HTTPMaximumConnectionsPerHost: Int
OBJECTIVE-C
@property NSInteger HTTPMaximumConnectionsPerHost
Discussion
This property determines the maximum number of simultaneous connections made to each host by tasks within sessions based on this configuration.
This limit is per session, so if you use multiple sessions, your app as a whole may exceed this limit. Additionally, depending on your connection to the Internet, a session may use a lower limit than the one you specify.
The default value is 6 in OS X, or 4 in iOS.
Availability
Available in iOS 7.0 and later.
我們可以看到身诺,默認(rèn)配置下,iOS對于同一個IP服務(wù)器的并發(fā)最大為4抄囚,OS X為6霉赡。而如果你沒有使用共享的Session,則可能會超過這個數(shù)幔托。
因此穴亏,如果能用共享的Session,還是用共享的吧柑司。有些許的網(wǎng)絡(luò)加速迫肖,也是一件不錯的事情,您說呢攒驰?