前言
WWDC2015上的一個(gè)亮點(diǎn)就是所有網(wǎng)絡(luò)連接默認(rèn)為HTTPS服務(wù),為此推出App Transport Security,該Session就介紹了相關(guān)App Transport Security的信息,同時(shí)也介紹了HTTP/2協(xié)議,以及NSURLSession的變化,主要內(nèi)容如下:
- App Transport Security
- HTTP/2 Protocol Support
- NSURLSession on watchOS
- NSURLSession API change
內(nèi)容
App Transport Security
由于HTTP協(xié)議采用明文傳輸信息,在整個(gè)傳輸過程中極易出現(xiàn)信息竊聽,甚至篡改,挾持的情況,Apple也考慮到越來越多的用戶使用著各式各樣的iOS App 簡稱ATS,同時(shí)把自己的各種信息甚至隱私的保護(hù)工作,都交給了他們所使用的App的開發(fā)者們,因此蘋果和開發(fā)者都有責(zé)任真正地保護(hù)用戶的敏感信息.為了讓App Transport Security,iOS9 SDK 默認(rèn)只支持HTTPS這樣具有安全保障的傳輸協(xié)議,簡單來說就是HTTP+TSL/SSL,是使用 TLS/SSL 加密的 HTTP 協(xié)議.(具體的關(guān)于HTTPS的知識(shí),還是推薦Google一下,全站 HTTPS 來了)
由于iOS9默認(rèn)只支持HTTPS,在最新SDK上編譯無論是以前還是現(xiàn)在的HTTP網(wǎng)絡(luò)請求,都無法正常訪問網(wǎng)絡(luò),控制臺(tái)會(huì)出現(xiàn)如下警告:
The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.
因?yàn)樵贏TS的默認(rèn)配置下,iOS9會(huì)自動(dòng)將所有http轉(zhuǎn)換為https進(jìn)行連接請求,就導(dǎo)致了沒有支持HTTPS的服務(wù)器端無法接受到這樣的請求.但又由于目前大量應(yīng)用仍只支持HTTP協(xié)議來訪問服務(wù)器,想要讓所有的應(yīng)用都轉(zhuǎn)向支持HTTPS,涉及到這些App的服務(wù)端,實(shí)現(xiàn)起來顯然是一件費(fèi)時(shí)費(fèi)力的事,于是Apple提供了一個(gè)折中的方案,算是過渡吧,就是在項(xiàng)目的Info.plist文件中可以自定義配置ATS,形式就是添加自定義的Exception,.下圖為Session所給了在Info.plist配置ATS的正確姿勢.
NSAppTransportSecurity為配置ATS的開關(guān)鍵,必須在Info.plist上手動(dòng)添加Raw,對(duì)應(yīng)的Application Category為App Transport Security Settings,圖上的NSExceptionDomains用表示需要定義的域名列表,除此之外NSAppTransportSecurity還有個(gè)鍵值對(duì)為NSAllowsArbitraryLoads,默認(rèn)為No,表示開啟所有域的ATS特性即只支持HTTPS傳輸除非在ExceptionDomains中自定義傳輸方式,而為Yes時(shí),則關(guān)閉了ATS特性即允許所有的HTTP或者HTTPS傳輸.而針對(duì)如何應(yīng)對(duì)各種網(wǎng)絡(luò)傳輸需求如何進(jìn)行ATS配置,推薦一篇南峰子大大的文章App Transport Security(ATS)
HTTP/2 Protocol Support
以前對(duì)HTTP/2不太了解,既然Session提到了,于是查看了維基百科對(duì)HTTP/2的定義,如下:
- HTTP/2(超文本傳輸協(xié)議第2版俯萌,最初命名為HTTP2.0),是HTTP協(xié)議的的第二個(gè)主要版本,于2015年5月正式發(fā)表
- 協(xié)議主要內(nèi)容為異步連接復(fù)用郭厌,頭壓縮和請求反饋管線化并保留與HTTP 1.1的完全語義兼容.
無疑HTTP/2就是為了解決HTTP/1.1所存在的一些數(shù)據(jù)加載,請求處理的性能問題而推出的,Apple也給出了關(guān)于HTTP/2與HTTP/1.1的不同之處.
而在對(duì)HTTP/2,Speaker明確提到在iOS9后NSURLSession支持(iOS9之前的版本只支持HTTP/1.1),而NSURLConnection不支持,官方也不推薦使用NSURLConnection API進(jìn)行網(wǎng)絡(luò)操作.而令開發(fā)者欣喜的是,不需要額外任何代碼,NSURLSession自動(dòng)支持了HTTP/2協(xié)議,只需要一個(gè)支持HTTP/2的服務(wù)器即可??????.(備注:HTTP/2協(xié)議對(duì)前端的影響還是很大的,建議也好好了解下談?wù)凥TTP/2對(duì)前端的影響)
NSURLSession on watchOS
關(guān)于watchOS上的網(wǎng)絡(luò)數(shù)據(jù)傳輸,同樣使用NSURLSession API在watchOS平臺(tái)上,也擁有ATS特性以及支持HTTP/2協(xié)議,并且Apple Watch在進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)請求時(shí)如果在藍(lán)牙配對(duì)的iPhone附近,則會(huì)讓iPhone進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)加載,然后將結(jié)果通過連接的藍(lán)牙傳輸?shù)絯atch上.對(duì)于watchOS上進(jìn)行網(wǎng)絡(luò)訪問的最佳實(shí)踐,該Session表示要謹(jǐn)記對(duì)watch的帶寬限制,下載不要將過大尺寸的圖片,盡量操作少量的網(wǎng)絡(luò)數(shù)據(jù).
NSURLSession API change
講到這部分時(shí)提到了對(duì)NSURLConnection API的棄用,也建議開發(fā)者使用NSURLSession相關(guān)API進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)操作,并且在WatchOS上只支持NSULRSession進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)傳輸.
Cookie的共享
iOS8推出了App Extension,如Notification center,App與其Extension都默認(rèn)對(duì)數(shù)據(jù)的持有進(jìn)行獨(dú)立處理,就像放在兩個(gè)不同的數(shù)據(jù)集合里,而現(xiàn)在可以讓App和其Extension共享同一個(gè)數(shù)據(jù)集合,具體示例如下:
let groupContainerIdentifier = "group.simon.mygroupname"
let cookieStorage = NSHTTPCookieStorage.sharedCookieStorageForGroupContainerIdentifier(groupContainerIdentifier)
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
config.HTTPCookieStorage = cookieStorage
let session = NSURLSession(configuration: config)
//...
NSURLSessionStreamTask
針對(duì)直接進(jìn)行TCP/IP連接的網(wǎng)絡(luò)操作API,此次帶來新的NSURLSessionStreamTask來,代替NSInputStream和NSOutputStream,并且API使用起來便捷容易.
//異步讀數(shù)據(jù)操作
let task = NSURLSession().streamTaskWithHostName("chat.example.com", port: 5555)
task.resume()
//task.startSecureConnection() //基于TSL進(jìn)行連接
task.readDataOfMinLength(16384, maxLength: 65536, timeout: 30.0) { (data, eof, error) -> Void in
}
//異步寫數(shù)據(jù)操作
let data = NSData()
task.writeData(data, timeout: 30.0) { (error) -> Void in
//...
}
另外也添加NSURLSessionStreamDelegate代理方法,用于跟蹤整個(gè)TCP連接的狀態(tài)過程.
public func URLSession(session: NSURLSession, readClosedForStreamTask streamTask: NSURLSessionStreamTask)
public func URLSession(session: NSURLSession, writeClosedForStreamTask streamTask: NSURLSessionStreamTask)
public func URLSession(session: NSURLSession, betterRouteDiscoveredForStreamTask streamTask: NSURLSessionStreamTask)
總結(jié)
自從iOS7之后,Apple就將NSURLConnection的相關(guān)API狀態(tài)改為deprecate,不推薦開發(fā)者再使用相關(guān)API進(jìn)行HTTP網(wǎng)絡(luò)連接,推薦使用NSURLSession的API,而現(xiàn)在Apple又在NSURLSession基礎(chǔ)上又增加了ATS特性,以及支持HTTP/2協(xié)議,以及在WatchOS上只能使用NSURLSession,無不說明了Apple對(duì)安全,高效的API的推崇,以及對(duì)用戶信息安全,隱私保護(hù)的看重,希望同廣大開發(fā)者一起營造更加安全的App環(huán)境.