URLSession Adaptable Connectivity API
當(dāng)網(wǎng)絡(luò)請(qǐng)求遇到不可達(dá)的情況時(shí),如:
- 無(wú)連接上Wifi且無(wú)手機(jī)信號(hào)
- 設(shè)備飛行模式
- 只有蜂窩信號(hào),但是allowsCellularAccess為NO
等,會(huì)導(dǎo)致請(qǐng)求直接失敗。很多APP通常這是時(shí)候回監(jiān)聽(tīng)網(wǎng)絡(luò)連接狀態(tài)以待可連接時(shí)重新請(qǐng)求或直接重新發(fā)起請(qǐng)求。
蘋(píng)果為了解決這個(gè),在URLSessionConfiguration中增加了waitsForConnectivity屬性,當(dāng)其設(shè)置為YES,系統(tǒng)回等到以上幾個(gè)請(qǐng)求不可達(dá)情況消失了才把請(qǐng)求發(fā)出去(避免無(wú)謂的請(qǐng)求失敗)。(此功能在BackgroundURLSession中默認(rèn)開(kāi)啟)
同時(shí)增加了
urlSession(_:taskIsWaitingForConnectivity:)
代理方法通知代理者某個(gè)請(qǐng)求等待連接可用
URLSession Scheduling API
主要解決一下三個(gè)問(wèn)題:
- 沒(méi)必要因?yàn)閯?chuàng)建NSURLSessionTask而進(jìn)行額外的后臺(tái)加載
- 當(dāng)后臺(tái)請(qǐng)求創(chuàng)建但還沒(méi)發(fā)出去的時(shí)候,這個(gè)被創(chuàng)建的請(qǐng)求有可能因?yàn)樯舷挛淖兓脑驅(qū)е逻@個(gè)請(qǐng)求無(wú)意義
- iOS系統(tǒng)并不知道什么時(shí)候去發(fā)起你的請(qǐng)求才是最合適的
原先你要做后臺(tái)數(shù)據(jù)加載的時(shí)候,流程是這樣的:
變成
所以當(dāng)應(yīng)用在前臺(tái)的時(shí)候,你就可以創(chuàng)建這個(gè)NSURLSessionTask,iOS11里面就不會(huì)在后臺(tái)額外launch一次去創(chuàng)建NSURLSessionTask。這就解決了問(wèn)題1。
iOS11在NSURLSessionTask的delegate里面提供了一個(gè)新的方法:urlSession:task:willBeginDelayedRequest:completionHandler:(Backgroud Session 專有)。系統(tǒng)在發(fā)起請(qǐng)求之前會(huì)調(diào)一個(gè)這個(gè)回調(diào),然后在這個(gè)completionHandler里面你告訴系統(tǒng)這個(gè)請(qǐng)求是否要發(fā)出去,是否要修改。從而解決了問(wèn)題2。
iOS11也給了NSURLSessionTask一個(gè)property:earliestBeginDate。系統(tǒng)在earlistBeginDate之前是不會(huì)發(fā)起這個(gè)請(qǐng)求的。你給這個(gè)task設(shè)置一個(gè)earliestBeginDate,就解決了問(wèn)題3。
還通過(guò)設(shè)置NSURLSessionTask的countOfBytesClientExpectsToSend和countOfBytesClientExpectsToReceive來(lái)讓系統(tǒng)更好地調(diào)度你的后臺(tái)網(wǎng)絡(luò)任務(wù)。
NSURLSession Enhancements
ProgressReporting
以往監(jiān)聽(tīng)URLSessionTask的進(jìn)度是通過(guò)KVO以下屬性來(lái)計(jì)算進(jìn)度
countOfBytesExpectedToReceive,countOfBytesReceived,countOfBytesExpectedToSend,countOfBytesSent
但是這樣需要做額外的工作
蘋(píng)果新增了屬性
var fractionCompleted:Double
來(lái)提供進(jìn)度
以及屬性
localizedDescription,localizedAdditionalDescription:
獲取進(jìn)度的描述
URLSession Brotli Support
URLSession支持Brotli壓縮協(xié)議
Brotli對(duì)比gzip,壓縮率提高了15%(HTML,CSS,JS...等)
URLSessionStreamTask
新增了HTTPS認(rèn)證的流程代理
注: URLSessionStreamTask特性
- 支持TCP/IP直連服務(wù)器
- 支持HTTPS
- 完全取代NSInputStream/NSOutputStream
Networking Best Practices
- 不使用BSD Socket
- 不使用embed networking Libaray
- 使用蘋(píng)果以下的API來(lái)獲得提升
- Wifi Assist
- Background work
- 使用域名相關(guān)API(就是不要直接使用IP)
- 使用timeoutIntervalForResource,timeoutIntervalForRequest設(shè)定請(qǐng)求超時(shí)時(shí)間
- 盡量一個(gè)app內(nèi)共用一個(gè)URLSession
- 即使清理動(dòng)態(tài)創(chuàng)建的URLSession,使用finishTasksAndInvalidate和invalidateAndCancel函數(shù)
Ongoing Developments
開(kāi)發(fā)TLS1.3中
開(kāi)發(fā)QUIC中
- 全名Quick UDP internet connections
- 由谷歌發(fā)起的