本文是逐行翻譯,便於參照原文,如有歧義或者疑問請閱讀原文比較。 於 2017.1.25
1.1 CustomHTTPProtocol shows how to use an NSURLProtocol subclass to intercept the HTTP/HTTPS requests made by a high-level subsystem that does not otherwise expose its network connections. In this specific case, it intercepts the requests made by a UIWebView in order to support custom server trust evaluation. You can use this technique to solve various problems, including: CustomHTTPProtocol為我們展示了怎樣利用NSURLProtocol子類來攔截更高層子系統中未暴露的網路請求連線的HTTP/HTTPs請求。在這個特定的小范例中,為了幫助使用者伺服器驗證,CustomHTTPProtocol攔截了UIWebview中的網路請求。你能用這項技術解決如下問題 o implementing custom HTTPS server trust evaluation in a UIWebView (perhaps to access a server with a self-signed certificate), as shown by this specific sample code 在UIWebView中實現自定義HTTPS伺服器信任評估(可能訪問具有自簽名證書的伺服器),如此特定示例程式碼所示 o allowing HTTPS client identity choice in a UIWebView 在UIWebView中允許HTTPS客戶端標識選擇 o supporting HTTP (RFC 2617) authentication in a UIWebView 在UIWebView中支援HTTP(RFC 2617)認證 o debugging problems with any subsystem that uses NSURL{Session,Connection}, especially in situations where it uses HTTPS, and thus is not amenable(經得起檢驗的,易控制的) to packet tracing 除錯任何使用NSURL {Session,Connection}的子系統,特別是在使用HTTPS的情況下,因此不適合包跟蹤 Additionally, the core technique shown by this sample (an NSURLProtocol subclass) can be used to solve other problems including: 此外,此示例(NSURLProtocol子類)展示的核心技術也可用於解決其他問題,包括: o forcing UIWebView to run through a custom proxy (easy to set up in the NSURLSession used for the recursive requests) 讓UIWView執行在自定義的代理中(在NSURLSession中更容易設定遞迴請求) o running HTTP requests over some non-standard transport scheme (HTTP over an External Accessory stream pair, for example) 通過某些非標準傳輸方案(例如通過EAAccessory傳輸的HTTP請求)執行HTTP請求 注: External Accessory Framework是提供了配件連線iOS裝置的通道。開發者可以通過它來開發連線配件的app。 o supporting custom URL schemes for HTTP Live Streaming encryption keys 支援HTTP Live Streaming加密金鑰的自定義URL方案 CustomHTTPProtocol requires iOS 7 or later, although the NSURLProtocol subclass technique should work on any version of iOS and, for that matter, on Mac OS X 10.5 and later. CustomHTTPProtocol需要iOS 7或更高版本,但是NSURLProtocol子類技術應該可以在任何版本的iOS上執行,在Mac OS X 10.5及更高版本上也是如此。 IMPORTANT: Before using the technique shown by this sample, review the "Compatibility Notes" section, below. 重要資訊:在使用此示例所示的技術之前,請檢視下面的“相容性說明”部分。 Packing List
The sample includes three top-level items: 該示例包括三個頂級專案: o Read Me About CustomHTTPProtocol.txt -- This document. o Read Me關於CustomHTTPProtocol.txt - 本文件。 o CustomHTTPProtocol.xcodeproj -- An Xcode project for the sample. o CustomHTTPProtocol.xcodeproj - 樣本的Xcode專案。 o CustomHTTPProtocol -- A directory containing all the other stuff. o CustomHTTPProtocol - 包含所有其他內容的目錄。 Within the "CustomHTTPProtocol" directory you will find: 在“CustomHTTPProtocol”目錄中,您將找到: o Info.plist, main.m, Main.storyboard, Icons, Default Images -- Standard things you might find in any iOS app. Info.plist,main.m,Main.storyboard,Icons,Default Images - 您可以在任何iOS應用程式中找到的標準內容。 o AppDelegate.{h,m} -- The application delegate class; this is a normal app delegate with some minor additions to a) enable the NSURLProtocol subclass, b) support logging from that subclass, and c) actually do the custom server trust evaluation (via a delegate callback from the NSURLProtocol subclass). o AppDelegate。{h,m} - 應用程式委託類; 這是一個普通的應用程式代理,有一些小的g改動 a)啟用NSURLProtocol子類,b)支援從該子類的日誌記錄,和c)做自定義伺服器評估(通過從NSURLProtocol子類的委託回撥)。 o ThreadInfo.{h,m} -- A helper class used by the app delegate logging code. o ThreadInfo。{h,m} - 由應用程式委託日誌記錄程式碼使用的助手類。 o WebViewController.{h,m} -- The main view controller, which runs a web view and manages the process of downloading anchor certificates. 主檢視控制器,它執行Web檢視並管理下載錨點證書的過程。 o WebViewControllerHTML -- Some HTML files used by the above. o WebViewControllerHTML - 上面程式碼需要使用的一些HTML檔案。 o CredentialsManager.{h,m} -- A singleton model object that maintains the list of trusted anchors for the app. o CredentialsManager。{h,m} - 一個單例模型物件,維護應用程式的可信錨的列表。 o Core Code -- The code that actually implements the NSURLProtocol subclass. Within this directory you'll find four modules: o核心程式碼 - 實際實現NSURLProtocol子類的程式碼。在此目錄中,您將找到四個模組:
-
CustomHTTPProtocol.{h,m} -- The actual NSURLProtocol subclass. CustomHTTPProtocol。{h,m} - 實際的NSURLProtocol子類。
-
QNSURLSessionDemux.{h,m} -- A helper class used by instances of the CustomHTTPProtocol class to demultiplex NSURLSession delegate events. QNSURLSessionDemux。{h,m} - 由CustomHTTPProtocol類的例項用於解構NSURLSession委託事件的輔助類。
-
CanonicalRequest.{h,m} -- A module that contains a single function, CanonicalRequestForRequest, which implements some standard functionality. See the "Caveats" section (below) for more information about this. CanonicalRequest。{h,m} - 包含單個函式CanonicalRequestForRequest的模組,它實現了一些標準功能。有關詳細資訊,請參閱“注意事項”部分(如下)。
-
CacheStoragePolicy.{h,m} -- A module that contains a single function, CacheStoragePolicyForRequestAndResponse, which implements some standard functionality. See the "Compatibility Notes" section (below) for more information about this. CacheStoragePolicy。{h,m} - 包含單個函式CacheStoragePolicyForRequestAndResponse的模組,它實現了一些標準功能。有關詳細資訊,請參閱“相容性註釋”部分(如下)。
Using the Sample使用範例程式碼
To use the sample, simply run it on a device or the simulator. It will put up a web view that allows you to pick a number of sites to visit. To run a basic test, do the following: 要使用示例,只需在裝置或模擬器上執行它。它會展示一個網路檢視,允許你選擇一些網站進行訪問。要執行基本測試,請執行以下操作: \1. tap on the "CAcert (HTTPS)" link; you will see an error because the system does not trust the CAcert anchor by default 1.點選“CAcert(HTTPS)”連結; 您將看到錯誤,因為系統預設不信任CAcert錨點 \2. tap the Sites button to get you back to the top 2.點選網站按鈕,回到頂部 \3. tap the "Install CAcert Anchor" link, which takes you to the CAcert anchor install page 3.點選“安裝CAcert錨點”連結,將連結轉到CAcert錨點安裝頁面 \4. tap the Install button; wait for the CAcert anchor to install 4.點選安裝按鈕; 等待CAcert錨點安裝 Note: This affects only the CustomHTTPProtocol app, not the system as a whole. 注意:這僅影響CustomHTTPProtocol應用程式,而不影響整個系統。 \5. tap the Sites button to take you back to the top again 5.點選“站點”按鈕,將您帶回到頂端 \6. tap the "CAcert (HTTPS)" link; this time the site will be displayed because the UIWebView in this app now trusts the CAcert anchor 6.點選“CAcert(HTTPS)”連結; 此時將顯示網站,因為此應用程式中的UIWebView現在信任CAcert錨點 IMPORTANT: The app does not remember your installed anchors from launch to launch. See the "Caveats" section (below) for an explanation. 重要資訊:該應用程式不記得您從安裝啟動到安裝的錨點。有關說明,請參閱“注意事項”部分(如下)。 Building the Sample構建範例程式碼
The sample was built using Xcode 5.1.1 on OS X 10.9.4 using the iOS 7.1 SDK. You should be able to just open the project and choose Run from the Product menu. 該示例是使用Xcode 5.1.1在OS X 10.9.4使用iOS 7.1 SDK構建的。您應該只能開啟專案並從產品選單中選擇執行 Compatibility Notes相容性說明
This sample assumes that UIWebView uses NSURLConnection in a way that allows the NSURLProtocol subclass to affect its usage. This is currently true, but there's no guarantee that it will be true forever. Certainly, there are existing subsystems within iOS where this is not the case (for example, the movie playback subsystem). 此示例假設UIWebView使用NSURLConnection以允許NSURLProtocol子類能夠在UIWebView上生效。現在這是真實有效的,但不能保證它將永遠是真實有效的。當然,在iOS中存在不是這種情況的子系統(例如,電影回放子系統)。 WARNING: If you use an NSURLProtocol subclass to customize UIWebView's behaviour, you should file a bug that describes your requirements and requests that appropriate customization points be provided via the UIWebView delegate. 警告:如果使用NSURLProtocol子類來定製UIWebView的行為,您應該提交一個描述您的需求的錯誤,並請求通過UIWebView代理提供適當的自定義點。 developer.apple.com/bugreporter… Likewise, if you use this technique for other subsystems within iOS, you should file a bug requesting that those subsystems be enhanced to support the customization points that you require. 同樣,如果您對iOS中的其他子系統使用此技術,您應該提交一個錯誤,要求改造這些子系統以支援您需要的自定義點 If you plan to use a custom NSURLProtocol subclass for movie playback, watch WWDC 2011 Session 408 "HTTP Live Streaming Update" for important information about how NSURLProtocol subclasses interact with the media subsystem. 如果計劃使用自定義NSURLProtocol子類進行電影播放,請觀看WWDC 2011會話408“HTTP實時流更新”,瞭解有關NSURLProtocol子類與媒體子系統如何互動的重要資訊。 developer.apple.com/videos/wwdc… Be aware that, if a subsystem uses NSURLSession, your custom NSURLProtocol subclass will only see requests issued in the shared session (+[NSURLSession sharedSession]). For the protocol to work in other sessions, it must be listed (via the NSURLSessionConfiguration.protocolClasses property) in the configuration used to create the session. 請注意,如果子系統使用NSURLSession,您的自定義NSURLProtocol子類將只看到在共享會話(+ [NSURLSession sharedSession])中發出的請求。要使協議在其他會話中工作,必須在用於建立會話的配置中列出(通過NSURLSessionConfiguration.protocolClasses屬性)。 An NSURLProtocol subclass can potentially affect any piece of code in your process that uses NSURL{Session,Connection} and, as such, represents a real compatibility risk. To minimize the potential for problems: NSURLProtocol子類可能會影響程式中使用NSURL {Session,Connection}的任何程式碼段,因此代表了真正的相容性風險。為了儘量減少潛在的問題: o limit your scope -- The easiest way to prevent problems is to limit the type of URLs that you handle. To do this, implement +canInitWithRequest: so that it declines to process everything except the specific requests you're interested in. For example, while +canInitWithRequest: in this sample accepts both HTTP and HTTPS requests, it would be sufficient to have it accept only HTTPS requests, allowing HTTP requests to be processed by the default protocol implementation. o限制您的範圍 - 防止問題的最簡單方法是限制您處理的URL型別。為了做到這一點,實現+ canInitWithRequest:以便它拒絕處理除了你感興趣的特定請求之外的任何東西。例如,while + canInitWithRequest:在這個示例接受HTTP和HTTPS請求,它就足以讓它接受只有HTTPS請求,允許HTTP請求由預設協議實現處理。 o memory -- Be careful not to use too much memory, particularly on iOS. o記憶體 - 小心不要使用太多記憶體,特別是在iOS上。 o threading -- Be sure to follow the threading rules described below. o執行緒 - 請務必遵循下面描述的執行緒規則。 It's not possible to accurately implement an HTTP/HTTPS NSURLProtocol subclass without reimplementing some system functionality. Any time you reimplement system functionality you run the risk that the system functionality might change, leaving your reimplemention behind. There are two major areas of concern here: 不可能在不重新實現某些系統功能的情況下準確實現HTTP / HTTPS NSURLProtocol子類。每當您重新實現系統功能時,您都會遇到系統功能可能會改變的風險,因此您可以重新實現系統功能。這裡有兩個主要關注的領域: o URL canonicalization -- The code in the CanonicalRequestForRequest function is complex, and there's certainly some scope for future compatibility problems. o URL規範化 - CanonicalRequestForRequest函式中的程式碼很複雜,並且對於未來的相容性問題肯定有一定範圍。 o cache storage policy -- The code in the CacheStoragePolicyForRequestAndResponse function isn't nearly as complex as the URL canonicalization code, but it is another example of reimplementing system functionality. o快取儲存策略 - CacheStoragePolicyForRequestAndResponse函式中的程式碼不像URL規範化程式碼那麼複雜,但它是重新實現系統功能的另一個示例 Threading Notes執行緒註釋
NSURLProtocol subclasses are tricky to implement correctly. The most important issues relate to threading. The methods that an NSURLProtocol subclass is expected to implement can be split into two groups: NSURLProtocol子類很難正確實現。最重要的問題與執行緒有關。NSURLProtocol子類期望實現的方法可以分為兩組: o any thread -- These methods may be called from any thread and must be completely thread safe: o任何執行緒 - 這些方法可以從任何執行緒呼叫,並且必須完全執行緒安全: -initWithRequest:cachedResponse:client: -dealloc +canInitWithRequest: +canonicalRequestForRequest: +requestIsCacheEquivalent:toRequest: o client thread -- These methods are always called by the client thread: o客戶端執行緒 - 這些方法總是由客戶端執行緒呼叫: -startLoading -stopLoading The exact identity of the client thread is unspecified, but you can be assured that: 客戶端執行緒的確切標識未指定,但您可以放心: o -startLoading is called by the client thread o -startLoading由客戶端執行緒呼叫 o -stopLoading will be called by that same client thread o -stopLoading將由相同的客戶端執行緒呼叫 o -stopLoading will be called before -dealloc is called o -stopLoading將在呼叫-dealloc之前呼叫 o the client thread will run its run loop o客戶端執行緒將執行其執行迴圈 In addition, an NSURLProtocol subclass is expected to call the various methods of the NSURLProtocolClient protocol from the client thread, including all of the following: 此外,NSURLProtocol子類期望從客戶端執行緒呼叫NSURLProtocolClient協議的各種方法,包括以下所有方法: -URLProtocol:wasRedirectedToRequest:redirectResponse: -URLProtocol:didReceiveResponse:cacheStoragePolicy: -URLProtocol:didLoadData: -URLProtocolDidFinishLoading: -URLProtocol:didFailWithError: -URLProtocol:didReceiveAuthenticationChallenge: -URLProtocol:didCancelAuthenticationChallenge: The NSURLProtocol subclass must call the client callbacks in the expected order. This breaks down into three phases: NSURLProtocol子類必須以預期的順序呼叫客戶端回撥。這分為三個階段: \1. pre-response -- In the initial phase the NSURLProtocol can make any number of -URLProtocol:wasRedirectedToRequest:redirectResponse: and -URLProtocol:didReceiveAuthenticationChallenge: callbacks. 1.預響應 - 在初始化階段,NSURLProtocol可以建立任意數量的-URLProtocol:wasRedirectedToRequest:redirectResponse:和-URLProtocol:didReceiveAuthenticationChallenge:callbacks。 \2. response -- It must then call -URLProtocol:didReceiveResponse:cacheStoragePolicy: to indicate the arrival of a definitive response. \2. 響應 - 然後它必須呼叫-URLProtocol:didReceiveResponse:cacheStoragePolicy:來指示確定響應的到達。 \3. post-response -- After receiving a response it may then make any number of -URLProtocol:didLoadData: callbacks, followed by a -URLProtocolDidFinishLoading: callback. \3. 收到響應後 - 在接收到響應之後,它可以使用任意數量的-URLProtocol:didLoadData:callbacks,隨後是一個-URLProtocolDidFinishLoading:回撥。 The -URLProtocol:didFailWithError: callback can be made at any time (although keep in mind the following point). -URLProtocol:didFailWithError:可以隨時進行回撥(但請記住以下幾點)。 The NSURLProtocol subclass must only send one authentication challenge to the client at a time. After calling -URLProtocol:didReceiveAuthenticationChallenge:, it must wait for the client to resolve the challenge before calling any callbacks other than -URLProtocol:didCancelAuthenticationChallenge:. This means that, if the connection fails while there is an outstanding authentication challenge, the NSURLProtocol subclass must call -URLProtocol:didCancelAuthenticationChallenge: before calling -URLProtocol:didFailWithError:. NSURLProtocol子類只能一次向客戶端傳送一個身份驗證質詢。呼叫-URLProtocol:didReceiveAuthenticationChallenge:後,它必須等待客戶端解決挑戰,然後再呼叫任何回撥之外的-URLProtocol:didCancelAuthenticationChallenge:。這意味著,如果連線失敗,而有一個未完成的身份驗證質詢,NSURLProtocol子類必須呼叫-URLProtocol:didCancelAuthenticationChallenge:之前呼叫-URLProtocol:didFailWithError :. WARNING: An NSURLProtocol subclass must operate asynchronously. It is not safe for it to block the client thread for extended periods of time. For example, while it's reasonable for an NSURLProtocol subclass to defer work (like an authentication challenge) to the main thread, it must do so asynchronously. If the NSURLProtocol subclass passes a task to the main thread and then blocks waiting for the result, it's likely to deadlock the application. 警告:NSURLProtocol子類必須非同步操作。它不能安全地阻止客戶端執行緒很長一段時間。例如,雖然NSURLProtocol子類推遲到主執行緒的工作(如身份驗證質詢)是合理的,但它必須非同步執行。如果NSURLProtocol子類將任務傳遞給主執行緒,然後阻塞等待結果,它可能會死鎖應用程式。 Caveats 附加說明
The sample app does not remember your installed anchors from launch to launch. This would be easy to implement by extending the CredentialsManager class to store the anchors, but I chose not to do this in order to keep things simple. 示例應用程式不會記住從啟動到啟動安裝的錨點。這將很容易實現通過擴充套件CredentialsManager類來儲存錨點,但我選擇不這樣做,以保持簡單。 The NSURLProtocolClient protocol has not been extended to support advanced protection spaces rdar://problem/9226151. This means there's no way for your NSURLProtocol subclass to call the NSURLConnection delegate's -connection:canAuthenticateAgainstProtectionSpace: method. If you do send authentication challenges to your client, you must only send standard authentication challenges (that is, challenges whose protection space's authentication method is NSURLAuthenticationMethodDefault, NSURLAuthenticationMethodHTTPBasic, or NSURLAuthenticationMethodHTTPDigest). You must process other authentication challenges yourself (which is often the reason why you implemented the custom NSURLProtocol subclass in the first place). NSURLProtocolClient協議尚未擴充套件,以支援高階保護空間<rdar:// problem / 9226151>。這意味著您的NSURLProtocol子類無法呼叫NSURLConnection委託的-connection:canAuthenticateAgainstProtectionSpace:方法。如果您向客戶端傳送身份驗證挑戰,則您必須只傳送標準身份驗證挑戰(即,保護空間的身份驗證方法為NSURLAuthenticationMethodDefault,NSURLAuthenticationMethodHTTPBasic或NSURLAuthenticationMethodHTTPDigest的挑戰)。您必須自己處理其他身份驗證挑戰(這通常是您首先實現自定義NSURLProtocol子類的原因)。 Similarly, there is no way for your NSURLProtocol subclass to call the NSURLConnection delegate's -connection:needNewBodyStream: or -connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite: methods (rdar://problem/9226155 and rdar://problem/9226157). The latter is not a serious concern--it just means that your clients don't get upload progress--but the former is a real issue. If you're in a situation where you might need a second copy of a request body, you will need your own logic to make that copy, including the case where the body is a stream. 同樣,你的NSURLProtocol子類沒有辦法呼叫NSURLConnection委託的-connection:needNewBodyStream:或-connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:methods(<rdar:// problem / 9226155>和<rdar:// problem / 9226157 >)。後者不是一個嚴重的問題 - 這只是意味著你的客戶端不會獲得上傳進度 - 但前者是一個真正的問題。如果您遇到需要請求正文的第二個副本的情況,您需要使用自己的邏輯來進行該副本,包括正文是流的情況。 And finally, there is no way for your NSURLProtocol subclass to call the NSURLConnection delegate's -connectionShouldUseCredentialStorage: or -connection:willCacheResponse: methods (rdar://problem/9226160). This shouldn't be a problem in most circumstances, but could cause problems for complex clients. 最後,你的NSURLProtocol子類沒有辦法呼叫NSURLConnection委託的-connectionShouldUseCredentialStorage:或-connection:willCacheResponse:methods(<rdar:// problem / 9226160>)。這在大多數情況下不應該是問題,但可能對複雜的客戶端造成問題。 Creating an NSHTTPURLResponse from scratch is tricky. This sample gets around the issue by calling NSURLConnection recursively, which causes the system to create the NSHTTPURLResponse on its behalf. If you need to do something different, see the "Creating an NSHTTPURLResponse" section below. 從頭開始建立NSHTTPURLResponse是棘手的。此示例通過遞迴呼叫NSURLConnection來解決問題,這導致系統代表它建立NSHTTPURLResponse。如果您需要執行不同的操作,請參閱下面的“建立NSHTTPURLResponse”部分。 Using a custom NSURLProtocol subclass can cause CFNetwork to leak on HTTP redirects rdar://problem/10093777. To reduce the impact of this leak, minimize the size of your NSURLProtocol subclass object and have it clean up its resources in -stopLoading rather than in -dealloc. 使用自定義NSURLProtocol子類可能導致CFNetwork在HTTP重定向<rdar:// problem / 10093777>上洩漏。為了減少此洩漏的影響,最小化NSURLProtocol子類物件的大小,並在-stopLoading中而不是在-dealloc中清除其資源。 The CanonicalRequest code would most definitely benefit from adopting the NSURLComponents class that was added in iOS 7 and OS X 10.9. The technique it currently uses is less than ideal rdar://problem/17383757. CanonicalRequest程式碼最有利於採用在iOS 7和OS X 10.9中新增的NSURLComponents類。它當前使用的技術不太理想<rdar:// problem / 17383757>。 Creating an NSHTTPURLResponse 建立NSHTTPURLResponse
Prior to iOS 5 (and OS X 10.7) there was no supported way to construct a valid NSHTTPURLResponse from scratch rdar://problem/5817126. The sticking point was that the only public initialisation method (-initWithURL:MIMEType:expectedContentLength:textEncodingName:) did not let you specify the HTTP status code or headers. Moreover, because of the interactions between NSURLConnection and CFNetwork, you can't work around this limitation by subclassing NSHTTPURLResponse and overriding the -statusCode and -allHeaderFields methods; such overrides are not seen by all subsystems that use NSURLConnection (most notably UIWebView). 在iOS 5(和OS X 10.7)之前,沒有支援的方法從頭構建有效的NSHTTPURLResponse <rdar:// problem / 5817126>。關鍵點是,唯一的公共初始化方法(-initWithURL:MIMEType:expectedContentLength:textEncodingName :)不允許您指定HTTP狀態程式碼或標頭。此外,由於NSURLConnection和CFNetwork之間的互動,您不能通過子類化NSHTTPURLResponse並覆蓋-statusCode和-allHeaderFields方法來解決此限制; 這樣的覆蓋不是所有使用NSURLConnection(最引人注目的UIWebView)的子系統。 If you only support iOS 5 or later, this isn't an issue: when you need to construct an NSHTTPURLResponse, simply use the newly introduced -initWithURL:statusCode:HTTPVersion:headerFields: initialisation method. However, if you must support older systems, things get more complex. There are a variety of less-than-ideal workarounds: 如果你只支援iOS 5或更高版本,這不是一個問題:當你需要構造一個NSHTTPURLResponse,只需使用新引入的-initWithURL:statusCode:HTTPVersion:headerFields:initialisation方法。但是,如果您必須支援舊系統,則事情變得更復雜。有多種不太理想的解決方法: o Actually pass the request off to the default HTTP or HTTPS implementation by calling NSURL{Session,Connection} recursively. This will give you back an NSHTTPURLResponse that you can pass up to your client. o實際上通過遞迴呼叫NSURL {Session,Connection}將請求傳遞給預設的HTTP或HTTPS實現。這將給你一個NSHTTPURLResponse,你可以傳遞給你的客戶端。 This is the approach shown by this sample. 這是此示例顯示的方法。 o An extension of this approach is to implement a small loopback web server that returns the HTTP response you need to generate the correct NSHTTPURLResponse. o這種方法的擴充套件是實現一個小的環回Web伺服器,它返回生成正確的NSHTTPURLResponse所需的HTTP響應。 o NSHTTPURLResponse supports the NSCoding protocol. If your NSURLProtocol only needs to return a small number of fixed responses, you could create those responses via NSURL{Session,Connection} at build time, archive them, and then unarchive them at run time. o NSHTTPURLResponse支援NSCoding協議。如果您的NSURLProtocol只需要返回少量的固定響應,您可以在構建時通過NSURL {Session,Connection}建立這些響應,將它們存檔,然後在執行時取消存檔。 Credits and Version History
If you find any problems with this sample, please file a bug against it. developer.apple.com/bugreporter… 1.0d1..8 (2011..2013) shipped to a limited number of developers on a one-to-one basis. 1.0 (Aug 2013) was the first shipping version. 1.1 (Jul 2014) is an update that changes the protocol to use NSURLSession for its recursive requests. This works around a deadlock issue rdar://problem/17342579 and makes the code more future proof. There were also numerous other minor changes. Share and Enjoy Apple Developer Technical Support Core OS/Hardware 28 Jul 2014