2018-07-19

NSURLRequest

概述

NSURLRequest封裝了加載請(qǐng)求的兩個(gè)基本數(shù)據(jù)元素:要加載的URL,以及在查詢實(shí)現(xiàn)提供的URL內(nèi)容緩存時(shí)要使用的策略。

重要的

這個(gè)類只用于封裝關(guān)于URL請(qǐng)求的信息。您必須使用其他類(如URLSession)將這些請(qǐng)求發(fā)送到服務(wù)器。

NSURLRequest被設(shè)計(jì)成通過創(chuàng)建擴(kuò)展來支持其他協(xié)議,這些擴(kuò)展為您自己的特定于協(xié)議的屬性提供訪問器方法。這些方法可以通過調(diào)用URLProtocol methods屬性(forKey:in:)和setProperty(_:forKey:in:)來獲取和設(shè)置實(shí)際值。

NSURLRequest的可變子類是NSMutableURLRequest。

重要的

Foundation框架的Swift覆蓋提供了URLRequest結(jié)構(gòu),它連接到NSURLRequest類及其可變子類NSMutableURLRequest。


UIWebView

在應(yīng)用程序中嵌入web內(nèi)容的視圖。

SDK ? 在iOS 2.0 - -12.0棄用

框架 ??UIKit

請(qǐng)注意

在iOS 8及以后運(yùn)行的應(yīng)用程序中,使用WKWebView類而不是使用UIWebView。此外,如果呈現(xiàn)不應(yīng)該運(yùn)行JavaScript的文件,請(qǐng)考慮將WKPreferences屬性JavaScript設(shè)置為false。


WKWebView

顯示交互式web內(nèi)容的對(duì)象,如應(yīng)用程序內(nèi)的瀏覽器。

SDK ? 在 iOS?8.0+????macOS 10.10 +?使用

框架 ??WebKit

重要的

從iOS 8.0和OS X 10.10開始,使用WKWebView向應(yīng)用中添加web內(nèi)容。不要使用UIWebView或WebView。

您可以使用WKWebView類在應(yīng)用程序中嵌入web內(nèi)容。為此,創(chuàng)建一個(gè)WKWebView對(duì)象,將其設(shè)置為視圖,并發(fā)送一個(gè)請(qǐng)求來加載web內(nèi)容。

請(qǐng)注意

您可以在WKWebView中使用httpBody內(nèi)容發(fā)出POST請(qǐng)求。

在使用init(frame:configuration:)方法創(chuàng)建一個(gè)新的WKWebView對(duì)象之后,需要加載web內(nèi)容。使用loadHTMLString(_:baseURL:)方法開始加載本地HTML文件或load(_:)方法開始加載web內(nèi)容。使用stopLoading()方法停止加載,使用isLoading屬性確定web視圖是否正在加載。將委托屬性設(shè)置為符合WKUIDelegate協(xié)議的對(duì)象,以跟蹤web內(nèi)容的加載。參見清單1以編程方式創(chuàng)建WKWebView的示例。

清單1

以編程方式創(chuàng)建一個(gè)WKWebView

import UIKit

import WebKit

class ViewController: UIViewController, WKUIDelegate {

? ? var webView: WKWebView!

? ??? ? override func loadView() {

? ? ? ? let webConfiguration = WKWebViewConfiguration()

? ? ? ? webView = WKWebView(frame: .zero, configuration: webConfiguration)

? ? ? ? webView.uiDelegate = self

? ? ? ? view = webView

? ? }

? ? override func viewDidLoad() {

? ? ? ? super.viewDidLoad()

? ? ? ? let myURL = URL(string:ps://www.apple.com")

? ? ? ? let myRequest = URLRequest(url: myURL!)

? ? ? ? webView.load(myRequest)

? ? }}

要允許用戶在頁面歷史中前后移動(dòng),可以使用goBack()和goForward()方法作為按鈕的操作。使用canGoBack和canGoForward屬性,在用戶無法朝某個(gè)方向移動(dòng)時(shí)禁用按鈕。

默認(rèn)情況下,web view會(huì)自動(dòng)將出現(xiàn)在web內(nèi)容中的電話號(hào)碼轉(zhuǎn)換為電話鏈接。當(dāng)一個(gè)電話連接被監(jiān)聽時(shí),手機(jī)應(yīng)用程序就會(huì)啟動(dòng)并撥通號(hào)碼。要關(guān)閉此默認(rèn)行為,請(qǐng)使用不包含phoneNumber標(biāo)志的WKDataDetectorTypes位字段設(shè)置datadectortypes屬性。

還可以使用set放大率(_:centeredAt:)在web內(nèi)容第一次顯示在web視圖中時(shí)以編程方式設(shè)置它的比例。之后,用戶可以使用手勢(shì)來改變縮放比例。


URLSession

協(xié)調(diào)一組相關(guān)網(wǎng)絡(luò)數(shù)據(jù)傳輸任務(wù)的對(duì)象。

SDK ? 在 iOS 7.0 + ? ? ? macOS 10.9 + ? ????tvo 9.0 + ? ?????watchOS 2.0 +?使用

概述

URLSession類和相關(guān)類為下載內(nèi)容提供了一個(gè)API。這個(gè)API為支持身份驗(yàn)證提供了一組豐富的委托方法,并使應(yīng)用程序能夠在應(yīng)用程序不運(yùn)行時(shí)執(zhí)行后臺(tái)下載,或者在iOS中,當(dāng)應(yīng)用程序暫停時(shí)執(zhí)行后臺(tái)下載。

重要的

URLSession API涉及到許多不同的類,它們以一種相當(dāng)復(fù)雜的方式協(xié)同工作,如果您自己閱讀參考文檔,這可能并不明顯。在使用此API之前,您應(yīng)該閱讀URL加載系統(tǒng)主題的概述。第一步部分中的文章提供了使用URLSession執(zhí)行常見任務(wù)的示例。

使用URLSession API,您的應(yīng)用程序創(chuàng)建一個(gè)或多個(gè)會(huì)話,每個(gè)會(huì)話協(xié)調(diào)一組相關(guān)的數(shù)據(jù)傳輸任務(wù)。例如,如果您正在創(chuàng)建一個(gè)web瀏覽器,您的應(yīng)用程序可能會(huì)為每個(gè)選項(xiàng)卡或窗口創(chuàng)建一個(gè)會(huì)話,或者一個(gè)會(huì)話用于交互式使用,另一個(gè)會(huì)話用于后臺(tái)下載。在每個(gè)會(huì)話中,您的應(yīng)用程序添加一系列任務(wù),每個(gè)任務(wù)表示對(duì)特定URL的請(qǐng)求(如果需要,遵循HTTP重定向)。

類型的URL會(huì)話

給定URL會(huì)話中的任務(wù)共享一個(gè)公共會(huì)話配置對(duì)象,該對(duì)象定義了連接行為,例如對(duì)單個(gè)主機(jī)進(jìn)行的最大同時(shí)連接數(shù)量,是否允許通過蜂窩網(wǎng)絡(luò)進(jìn)行連接,等等。

URLSession有一個(gè)用于基本請(qǐng)求的單例共享會(huì)話(它沒有配置對(duì)象)。它不像您創(chuàng)建的會(huì)話那樣可定制,但如果您有非常有限的需求,它是一個(gè)很好的起點(diǎn)。通過調(diào)用共享類方法訪問此會(huì)話。對(duì)于其他類型的會(huì)話,您使用以下三種配置之一實(shí)例化URLSession:

默認(rèn)會(huì)話的行為類似于共享會(huì)話,但允許進(jìn)行更多配置,并允許您使用委托增量地獲取數(shù)據(jù)。

短暫的會(huì)話與共享會(huì)話類似,但是不要向磁盤寫入緩存、cookie或憑據(jù)。

后臺(tái)會(huì)話允許您在應(yīng)用程序不運(yùn)行時(shí)在后臺(tái)執(zhí)行內(nèi)容的上傳和下載。

有關(guān)創(chuàng)建每種配置類型的詳細(xì)信息,請(qǐng)參見在URLSessionConfiguration類中創(chuàng)建會(huì)話配置對(duì)象。

URL會(huì)話任務(wù)的類型

在會(huì)話中,您可以創(chuàng)建任務(wù),可選地將數(shù)據(jù)上載到服務(wù)器,然后以磁盤上的文件或內(nèi)存中的一個(gè)或多個(gè)NSData對(duì)象的形式從服務(wù)器檢索數(shù)據(jù)。URLSession API提供了三種類型的任務(wù):

數(shù)據(jù)任務(wù)使用NSData對(duì)象發(fā)送和接收數(shù)據(jù)。數(shù)據(jù)任務(wù)是用于向服務(wù)器發(fā)出簡(jiǎn)短的、通常是交互式的請(qǐng)求。

上傳任務(wù)與數(shù)據(jù)任務(wù)類似,但它們也發(fā)送數(shù)據(jù)(通常以文件的形式),并在應(yīng)用程序不運(yùn)行時(shí)支持后臺(tái)上傳。

下載任務(wù)以文件的形式檢索數(shù)據(jù),并且在應(yīng)用程序沒有運(yùn)行時(shí)支持后臺(tái)下載和上傳。

使用一個(gè)會(huì)話委托

會(huì)話中的任務(wù)還共享一個(gè)公共委托,該委托允許您在發(fā)生各種事件時(shí)提供和獲取信息——當(dāng)身份驗(yàn)證失敗時(shí),當(dāng)來自服務(wù)器的數(shù)據(jù)到達(dá)時(shí),當(dāng)數(shù)據(jù)準(zhǔn)備緩存時(shí),等等。使用URL會(huì)話可以逐步地列出會(huì)話執(zhí)行任務(wù)時(shí)發(fā)生的事件,以及調(diào)用哪個(gè)委托方法。

另一方面,如果您不需要委托提供的任何特性,您可以在創(chuàng)建會(huì)話時(shí)使用這個(gè)API,而不提供一個(gè)通過nil的方法。

重要的

會(huì)話對(duì)象保存對(duì)委托的強(qiáng)引用,直到應(yīng)用程序退出或顯式地使會(huì)話無效為止。如果你不讓會(huì)話失效,你的應(yīng)用程序會(huì)泄漏內(nèi)存,直到它退出。

異步性和URL會(huì)話

與大多數(shù)網(wǎng)絡(luò)API一樣,URLSession API是高度異步的。它以兩種方式向應(yīng)用程序返回?cái)?shù)據(jù),具體取決于您調(diào)用的方法:

通過調(diào)用一個(gè)完成處理程序塊,當(dāng)傳輸完成成功或有錯(cuò)誤時(shí)。

通過調(diào)用會(huì)話委托上的方法作為接收數(shù)據(jù)和傳輸完成時(shí)的方法。

除了向委托交付這些信息之外,URLSession API還提供了狀態(tài)和進(jìn)度屬性,如果您需要根據(jù)任務(wù)的當(dāng)前狀態(tài)進(jìn)行編程決策,您可以查詢這些屬性(需要注意的是,它的狀態(tài)隨時(shí)都可能改變)。

URL會(huì)話還支持取消、重新啟動(dòng)或恢復(fù)、暫停任務(wù),并提供恢復(fù)暫停、取消或失敗下載的能力。

協(xié)議支持

URLSession類本機(jī)支持?jǐn)?shù)據(jù)、文件、ftp、http和https URL方案,對(duì)代理服務(wù)器和SOCKS網(wǎng)關(guān)進(jìn)行透明的支持,在用戶的系統(tǒng)首選項(xiàng)中配置。

URLSession支持HTTP/1.1、SPDY和HTTP/2協(xié)議。RFC 7540描述了HTTP/2支持,并要求服務(wù)器支持ALPN或NPN進(jìn)行協(xié)議協(xié)商。

您還可以通過子類化URLProtocol為您自己的自定義網(wǎng)絡(luò)協(xié)議和URL計(jì)劃(為您的應(yīng)用程序的私有使用)添加支持。

App Transport Security (ATS)

從iOS 9.0和OS X 10.11開始,默認(rèn)情況下,所有使用URLSession建立的HTTP連接都會(huì)啟用一個(gè)名為App Transport security (ATS)的新安全特性。ATS要求HTTP連接使用HTTPS (RFC 2818)。

使用一個(gè)URL會(huì)話

使用URLSession類發(fā)出請(qǐng)求:

1. 創(chuàng)建一個(gè)會(huì)話配置。對(duì)于后臺(tái)會(huì)話,此配置必須包含唯一標(biāo)識(shí)符。存儲(chǔ)該標(biāo)識(shí)符,并在應(yīng)用程序崩潰或終止或暫停時(shí)使用它與會(huì)話重新關(guān)聯(lián)。

2. 創(chuàng)建一個(gè)會(huì)話,指定一個(gè)配置對(duì)象和一個(gè)可選的委托。

3. 在會(huì)話中創(chuàng)建任務(wù)對(duì)象,每個(gè)對(duì)象表示一個(gè)資源請(qǐng)求。這些任務(wù)對(duì)象是URLSessionTask-URLSessionDataTask、URLSessionUploadTask或URLSessionDownloadTask的子類,具體取決于您試圖實(shí)現(xiàn)的行為。每個(gè)任務(wù)都以暫停狀態(tài)開始。在應(yīng)用程序調(diào)用任務(wù)的resume()之后,它開始下載指定的資源。

啟動(dòng)任務(wù)后,會(huì)話調(diào)用其委托的方法,如下:

1. 如果與服務(wù)器的初始握手需要連接級(jí)別的挑戰(zhàn)(比如SSL客戶端證書),則URLSession調(diào)用URLSession (_:task:didReceive:completionHandler:)或URLSession (_:didReceive:completionHandler:)委托方法。

2. 如果從流中提供任務(wù)的數(shù)據(jù),則URLSession對(duì)象調(diào)用委托的URLSession (_:task:needNewBodyStream:)委托方法來獲取InputStream實(shí)例,該實(shí)例為新請(qǐng)求提供主體數(shù)據(jù)。

3. 在將主體內(nèi)容初始上載到服務(wù)器(如果適用的話)期間,委托定期接收urlSession(_:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:)回調(diào),報(bào)告上傳進(jìn)度。

4. 服務(wù)器發(fā)送一個(gè)響應(yīng)。

5. 如果響應(yīng)表明需要身份驗(yàn)證,會(huì)話將調(diào)用其委托的urlSession(_:task:didReceive:completionHandler:)方法。回到步驟2。

6. 如果響應(yīng)是一個(gè)HTTP重定向響應(yīng),URLSession對(duì)象調(diào)用委托的URLSession(_:任務(wù):willPerformHTTPRedirection:newRequest:completionHandler:)方法。該委托方法使用提供的NSURLRequest對(duì)象(跟蹤重定向)、新的NSURLRequest對(duì)象(重定向到不同的URL)或nil(將重定向的響應(yīng)主體視為有效響應(yīng)并將其作為結(jié)果返回)來調(diào)用提供的完成處理程序。

? ? — 如果您決定遵循重定向,請(qǐng)回到步驟2。

????— 如果委托沒有實(shí)現(xiàn)此方法,那么重定向?qū)⒈桓櫟街囟ㄏ虻淖畲髷?shù)量。

7. 對(duì)于通過調(diào)用downloadTask(with resumedata:)或downloadTask(with resumedata:)創(chuàng)建的下載(或重新下載)任務(wù),URLSession使用新的任務(wù)對(duì)象調(diào)用委托的URLSession (_:downloadTask:didResumeAtOffset:expected tedtotalbytes:)方法。

8. 對(duì)于數(shù)據(jù)任務(wù),URLSession對(duì)象調(diào)用委托的URLSession (_:dataTask:didReceive:completionHandler:)方法。決定是否將數(shù)據(jù)任務(wù)轉(zhuǎn)換為下載任務(wù),然后調(diào)用完成處理程序來轉(zhuǎn)換、繼續(xù)或取消任務(wù)。如果您的應(yīng)用程序選擇將數(shù)據(jù)任務(wù)轉(zhuǎn)換為下載任務(wù),URLSession以新的下載任務(wù)為參數(shù)調(diào)用委托的URLSession (_:dataTask:didBecome:)方法。在此調(diào)用之后,委托不再接收來自數(shù)據(jù)任務(wù)的進(jìn)一步回調(diào),并開始接收來自下載任務(wù)的回調(diào)。

9. 在從服務(wù)器進(jìn)行傳輸期間,委托定期接收任務(wù)級(jí)回調(diào),以報(bào)告?zhèn)鬏斶M(jìn)度。對(duì)于數(shù)據(jù)任務(wù),會(huì)話調(diào)用委托的urlSession(_:dataTask:didReceive:)方法,并在接收數(shù)據(jù)時(shí)調(diào)用它們的實(shí)際數(shù)據(jù)片段。對(duì)于一個(gè)下載任務(wù),會(huì)話調(diào)用委托的urlSession(_:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:)方法,成功寫入磁盤的字節(jié)數(shù)。如果用戶告訴應(yīng)用程序暫停下載,通過調(diào)用cancel(通過producingresumedata:)方法取消任務(wù)。稍后,如果用戶要求您的應(yīng)用程序繼續(xù)下載,則將返回的簡(jiǎn)歷數(shù)據(jù)傳遞給downloadTask(withResumeData:)或downloadTask(withResumeData:completionHandler:),以創(chuàng)建一個(gè)新的下載任務(wù),繼續(xù)下載。(步驟1)。

10. 對(duì)于一個(gè)數(shù)據(jù)任務(wù),URLSession對(duì)象可以調(diào)用委托的URLSession (_:dataTask:willCacheResponse:completionHandler:)方法。然后應(yīng)用程序應(yīng)該決定是否允許緩存。如果不實(shí)現(xiàn)此方法,默認(rèn)行為是使用會(huì)話配置對(duì)象中指定的緩存策略。如果響應(yīng)是多部分編碼的,會(huì)話可能再次調(diào)用委托的didReceiveResponse方法,然后是零個(gè)或多個(gè)額外的didReceiveData調(diào)用。如果發(fā)生這種情況,請(qǐng)轉(zhuǎn)到步驟8(處理didReceiveResponse調(diào)用)。

11. 如果下載任務(wù)成功完成,則URLSession對(duì)象調(diào)用任務(wù)的URLSession (_:downloadTask:didFinishDownloadingTo:)方法,該方法具有臨時(shí)文件的位置。應(yīng)用程序必須從這個(gè)文件中讀取響應(yīng)數(shù)據(jù),或者在這個(gè)委托方法返回之前將其移動(dòng)到一個(gè)永久位置。

12.如果下載任務(wù)成功完成,則URLSession對(duì)象調(diào)用任務(wù)的URLSession (_:downloadTask:didFinishDownloadingTo:)方法,該方法具有臨時(shí)文件的位置。應(yīng)用程序必須從這個(gè)文件中讀取響應(yīng)數(shù)據(jù),或者在這個(gè)委托方法返回之前將其移動(dòng)到一個(gè)永久位置。

13.?當(dāng)任何任務(wù)完成時(shí),URLSession對(duì)象調(diào)用委托的URLSession (_:task:didCompleteWithError:)方法,該方法具有錯(cuò)誤對(duì)象或nil(如果任務(wù)成功完成)。如果可以繼續(xù)下載任務(wù),則NSError對(duì)象的userInfo字典包含nsurlsessiondownloadtask_taskresumedata鍵的值。應(yīng)用程序應(yīng)該將此值傳遞給downloadTask(withResumeData:)或downloadTask(withResumeData:completionHandler:),以創(chuàng)建一個(gè)新的下載任務(wù),繼續(xù)現(xiàn)有的下載。如果任務(wù)無法恢復(fù),您的應(yīng)用程序應(yīng)該創(chuàng)建一個(gè)新的下載任務(wù),并從開始重新啟動(dòng)事務(wù)。在任何一種情況下,如果傳輸失敗(除了服務(wù)器錯(cuò)誤之外),請(qǐng)轉(zhuǎn)到步驟3(創(chuàng)建和恢復(fù)任務(wù)對(duì)象)。

14.?如果您不再需要會(huì)話,您可以通過調(diào)用invalidateAndCancel()(取消未完成的任務(wù))或finishTasksAndInvalidate()(允許未完成的任務(wù)在對(duì)象無效之前完成)來使其無效。如果您不取消會(huì)話,那么當(dāng)您的應(yīng)用程序終止時(shí),會(huì)話將自動(dòng)消失(除非它是一個(gè)有活動(dòng)任務(wù)的后臺(tái)會(huì)話)。在使會(huì)話無效之后,當(dāng)所有未完成的任務(wù)被取消或完成時(shí),會(huì)話調(diào)用委托的urlSession(_:didBecomeInvalidWithError:)方法。當(dāng)該委托方法返回時(shí),會(huì)話處理它對(duì)委托的強(qiáng)引用。

如果應(yīng)用程序取消正在進(jìn)行的下載,URLSession對(duì)象會(huì)調(diào)用委托的URLSession (_:task:didCompleteWithError:)方法,就好像發(fā)生了錯(cuò)誤一樣。

NSCopying行為

會(huì)話和任務(wù)對(duì)象遵循以下NSCopying協(xié)議:

當(dāng)你的應(yīng)用程序復(fù)制一個(gè)會(huì)話或任務(wù)對(duì)象時(shí),你會(huì)得到相同的對(duì)象。

當(dāng)你的應(yīng)用程序復(fù)制一個(gè)配置對(duì)象時(shí),你會(huì)得到一個(gè)可以獨(dú)立修改的新拷貝。

線程安全

URL會(huì)話API本身是線程安全的。您可以在任何線程上下文中自由地創(chuàng)建會(huì)話和任務(wù),當(dāng)您的委托方法調(diào)用所提供的完成處理程序時(shí),工作將自動(dòng)調(diào)度到正確的委托隊(duì)列上。

警告

您的urlSessionDidFinishEvents(forBackgroundURLSession:)會(huì)話委托方法可以在輔助線程上調(diào)用。但是,在iOS中,該方法的實(shí)現(xiàn)可能需要調(diào)用應(yīng)用程序中提供的完成處理程序(_:handleeventsforbackgrounddurlsession:completionHandler:)。您必須在主線程上調(diào)用完成處理程序。

上述是從蘋果文檔里翻譯過來的,沒有任何人為修飾加工,只是翻譯的有點(diǎn)晦澀難懂。對(duì)付著看吧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容