gpt4 book ai didi

ios - WKWebView不使用URLCache

转载 作者:行者123 更新时间:2023-12-01 16:12:21 26 4
gpt4 key购买 nike

我有一个使用UIWebView显示一些本地内容的应用程序。我也有一个自定义的URLCache来拦截请求并将其替换为本地内容:

class LocalWebViewCache: URLCache {
open override func cachedResponse(for request: URLRequest) -> CachedURLResponse? {
if url.absoluteString.range(of: "http://localhost") != nil {
return cacheDelegate?.handleRequest(request)
}

return nil
}
}

我将此缓存在 AppDelagate中注册为:

var cache: LocalWebViewCache = LocalWebViewCache(memoryCapacity: 20 * 1024 * 1024,
diskCapacity: 100 * 1024 * 1024,
diskPath: nil)
URLCache.shared = cache

现在一切正常。 苹果拒绝了新版本的应用程序,因为我使用的是 UIWebView并且已弃用,因此我将 UIWebView替换为 WKWebView,看来webkit不支持共享缓存( URLCache.shared)。

我试图用 WKWebViewURLProtocol拦截 WKURLSchemeHandler请求,但没有任何运气。

我将不胜感激。

URLProtocol代码:

Appdelagate中:

URLProtocol.registerClass(MyProtocol.self)

class MyProtocol: URLProtocol {
override class func canInit(with request: URLRequest) -> Bool {
print("canInit: \(String(describing: request.url))")
return true
}

override init(request: URLRequest, cachedResponse: CachedURLResponse?, client: URLProtocolClient?) {
print("init: \(String(describing: request.url))")

super.init(request: request, cachedResponse: cachedResponse, client: client)
}

override class func canonicalRequest(for request: URLRequest) -> URLRequest {
print("canonicalRequest: \(String(describing: request.url))")

return request
}

override func startLoading() {
print("startLoading: \(String(describing: request.url))")
}
}

在所有这些方法中,只有 canInit(with request: URLRequest)被调用,这不是很有帮助。

WKURLSchemeHandler代码:

class MySchemeHandler: NSObject, WKURLSchemeHandler {
func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
print("start: \(String(describing: urlSchemeTask.request.url?.absoluteString))")
}

func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {
print("stop: \(String(describing: urlSchemeTask.request.url?.absoluteString))")
}
}

webkit.configuration.setURLSchemeHandler(MySchemeHandler(), forURLScheme: "localhost")

webkit.load(URLRequest(url: URL(string: "localhost://google.com")!))

但是 webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask)webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask)都没有被调用。

编辑1 :通过在其URL的开头附加 localhost://来加载本地资源,并通过 WKURLSchemeHandler处理它:

let testStr = """
<!DOCTYPE html>
<html>
<head>
<title></title>
<link href="localhost://../styles/style.css" type="text/css" rel="stylesheet"/>
</head>
<body>

<p class="test_class1">This is a paragraph.</p>
<p class ="test_class2">This is another paragraph.</p>

</body>
</html>
"""

lazy var webView: WKWebView = {
let webConfiguration = WKWebViewConfiguration()
webConfiguration
.setURLSchemeHandler(MySchemeHandler(), forURLScheme: "localhost")
let webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.translatesAutoresizingMaskIntoConstraints = false
return webView
}()

webView.loadHTMLString(testStr, baseURL: URL(string: "localhost"))

class MySchemeHandler: NSObject, WKURLSchemeHandler {
let testCss = """
@font-face{
font-family: 'Special';
font-weight: normal;
font-style: normal;
src: url(../fonts/special.ttf);
}

.test_class1 {
font-weight: bold;
color: #007D6E;
font-family: 'Special' !important;
text-align: center !important;
}

.test_class2 {
font-weight: bold;
color: #FF7D6E;
text-align: center !important;
}
"""

func webView(_: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
print("start: \(String(describing: urlSchemeTask.request.url?.absoluteString))")

guard let url = urlSchemeTask.request.url else {
return
}

if url.absoluteString.contains("style.css") {
let data = Data(testCss.utf8)

urlSchemeTask.didReceive(URLResponse(url: url,
mimeType: "text/css",
expectedContentLength: data
.count,
textEncodingName: nil))
urlSchemeTask.didReceive(data)
urlSchemeTask.didFinish()
}
}

func webView(_: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {
print("stop: \(String(describing: urlSchemeTask.request.url?.absoluteString))")
}
}


在日志中,我可以看到 start方法被本地资源触发:
start: Optional("localhost://../styles/style.css")
start: Optional("localhost://../fonts/special.ttf")

但是如果我从 localhost://中删除 <link href="localhost://../styles/style.css" type="text/css" rel="stylesheet"/> start方法根本不会被触发。

最佳答案

由于返回了副本,因此在调用WKWebView.configuration的结果上设置处理程序无效。相反,您应该创建一个新的WKWebViewConfiguration实例,在其上设置您的处理程序,然后将其传递给WKWebView.init(frame:, configuration:):

self.schemeHandler = MySchemeHandler()
self.webview = WKWebView(frame: .zero, configuration: {
let webConfiguration = WKWebViewConfiguration()
webConfiguration.setURLSchemeHandler(self.schemeHandler,
forURLScheme: "localhost")
return webConfiguration
}())

关于ios - WKWebView不使用URLCache,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61673209/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com