nfa*_*chi 4 ios swift wkwebview
我尝试在 WKWebView 加载之前捕获要加载的 url。根据文档decidePolicyFor navigationAction(WKNavigationDelegate)应该可以完成这项工作,但我的问题是这个委托在新网址加载之后而不是之前被调用。
这是我写的扩展。
extension MyWebViewController: WKNavigationDelegate {
public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
guard let navigationURL = navigationAction.request.url else {
decisionHandler(.allow)
return
}
let forbiddenUrlPattern = Configuration.current.links.forbiddenUrlPattern
if forbiddenUrlPattern.matches(url: navigationURL) {
decisionHandler(.cancel)
showFullScreenError(error: .forbidden)
return
}
// Default policy is to allow navigation to any links the subclass doesn't know about
decisionHandler(.allow)
}
}
Run Code Online (Sandbox Code Playgroud)
*PS 匹配扩展会检查模式并且工作正常。现在的问题是,在调用此委托函数之前,forbiddenUrl 的内容显示了一段时间,然后错误页面出现在屏幕上,如果我关闭它,最后一个可见的网页来自禁止链接模式。
在实际将链接加载到 webView 中之前,有什么方法可以了解该链接吗?
我正在使用 Xcode 11.2.1 和 Swift 5.0
我写下了在这里找到的答案,它也可能对其他人有帮助。经过一番努力,我发现decisionHandler如果 url 是相对的(不是绝对 url),就不会被调用。那么为什么decisionHandler加载该页面后会被调用呢?我发现的答案是:当我们有像href:"/foo/ba"then 这样的 url 时,在调用该 url 后,它将加载并解析为www.domain.com/foo/ba,然后desicionHandler才被调用。当我想在 webView 中第一次加载 url 时
也只调用一次。didCommit
所以解决方案对我有帮助是向 webView 添加观察者
webView.addObserver(self, forKeyPath: "URL", options: [.new,.old], context: nil)
Run Code Online (Sandbox Code Playgroud)
和
override open func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
/// This observer is in addition to the navigationAction delegate to block relative urls and intrrupt them and do native
/// action if possible.
if let newValue = change?[.newKey] as? URL, let oldValue = change?[.oldKey] as? URL, newValue != oldValue {
let forbiddenUrlPattern = Configuration.current.links.forbiddenUrlPattern
if forbiddenUrlPattern.matches(url: newValue) {
showFullScreenError(error: .forbidden)
return
}
/// These two action needed to cancel the webView loading the offerDetail page.
/// otherwise as we stop loading the about to start process webView will show blank page.
webView.stopLoading()
///This is small extension for make webView go one step back
webView.handleBackAction(sender: newValue)
return
}
}
}
Run Code Online (Sandbox Code Playgroud)
因此,这个观察者除了decisionHandler可以覆盖任何人想要监听并在需要时采取行动的绝对和相对 URL。
| 归档时间: |
|
| 查看次数: |
4825 次 |
| 最近记录: |