我們正在爲iOS構建瀏覽器。我們決定嘗試使用自定義的NSURLProtocol
子類來實現我們自己的緩存方案並執行用戶代理欺騙。它能夠完成這兩件事情......問題在於,導航到某些網站(msn.com是最糟糕的)會導致整個應用程序的用戶界面凍結達15秒。顯然有些東西阻塞了主線程,但它不在我們的代碼中。NSURLProtocol + UIWebView +某些域=應用程序UI凍結
此問題只出現在UIWebView
和自定義協議的組合中。如果我們換一個WKWebView
(我們因各種原因不能使用),問題就消失了。同樣,如果我們沒有註冊協議,以至於它沒有被利用,問題就會消失。
它也似乎沒有太大的問題什麼協議;我們寫了一個毫無意義的虛擬協議,只是轉發響應(帖子的底部)。我們將該協議放入沒有任何其他代碼的裸機測試瀏覽器中 - 結果相同。我們也嘗試使用別人的(RNCachingURLProtocol
)並觀察到相同的結果。看起來,這兩個組件與某些頁面的簡單組合會導致凍結。我無法嘗試解決(甚至調查)此問題,並且非常感謝任何指導或提示。謝謝!
import UIKit
private let KEY_REQUEST_HANDLED = "REQUEST_HANDLED"
final class CustomURLProtocol: NSURLProtocol {
var connection: NSURLConnection!
override class func canInitWithRequest(request: NSURLRequest) -> Bool {
return NSURLProtocol.propertyForKey(KEY_REQUEST_HANDLED, inRequest: request) == nil
}
override class func canonicalRequestForRequest(request: NSURLRequest) -> NSURLRequest {
return request
}
override class func requestIsCacheEquivalent(aRequest: NSURLRequest, toRequest bRequest: NSURLRequest) -> Bool {
return super.requestIsCacheEquivalent(aRequest, toRequest:bRequest)
}
override func startLoading() {
var newRequest = self.request.mutableCopy() as! NSMutableURLRequest
NSURLProtocol.setProperty(true, forKey: KEY_REQUEST_HANDLED, inRequest: newRequest)
self.connection = NSURLConnection(request: newRequest, delegate: self)
}
override func stopLoading() {
connection?.cancel()
connection = nil
}
func connection(connection: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
self.client!.URLProtocol(self, didReceiveResponse: response, cacheStoragePolicy: .NotAllowed)
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {
self.client!.URLProtocol(self, didLoadData: data)
}
func connectionDidFinishLoading(connection: NSURLConnection!) {
self.client!.URLProtocolDidFinishLoading(self)
}
func connection(connection: NSURLConnection!, didFailWithError error: NSError!) {
self.client!.URLProtocol(self, didFailWithError: error)
}
}
嗨@Reid你找到了解決這個問題的方法嗎?我也有同樣的問題。 – Weizhi
@Reid,有什麼消息嗎?我有同樣的問題。 –
我不是那個我遇到這個問題的項目(甚至在那家公司),所以沒有在幾個月內看過它。使用CustomHTTPProtocol示例代碼(請參閱下面的@鮑里斯的答案)確實解決了這個問題,但我從來沒有能夠(a)完全隔離他們做了什麼,或者(b)使他們的協議適應我需要做的事情......但其中一種方法是你最好的選擇。 –