问题
How do I capture the redirection url in when using WKWebView like if a webpage redirects to another page on submitting the username and password or some other data. I need to capture the redirected url. Is there any method in WKNavigationDelegate to override?
回答1:
Use this WKNavigationDelegate method
public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Swift.Void) {
if(navigationAction.navigationType == .other) {
if navigationAction.request.url != nil {
//do what you need with url
//self.delegate?.openURL(url: navigationAction.request.url!)
}
decisionHandler(.cancel)
return
}
decisionHandler(.allow)
}
Hope this helps
回答2:
(This answers the slightly more general question of how to detect a URL redirection in WKWebView, which is the search that lead me to this page.)
Short answer
Use WKNavigationDelegate's webView(_:didReceiveServerRedirectForProvisionalNavigation:) function and examine WKWebView's URL property.
Longer answer
There are a couple of places you could detect a server-side redirect.
On iOS 10.3.3 and iOS 11.0, the sequence of events I observe when loading a URL that gets redirected by the server is:
The
WKNavigationDelegatefunctionwebView(_:decidePolicyFor:decisionHandler:)is called for the original URL request.WKWebView'sURLproperty is set to the original URL.The
WKNavigationDelegatefunctionwebView(_:didStartProvisionalNavigation:)is called for the original URL request.WKWebView'sURLproperty is set to the original URL.The
WKWebView'sURLproperty is updated by WebKit to the redirection URL. (You'll only know about this if you are key-value observing the property.)The
WKNavigationDelegatefunctionwebView(_:decidePolicyFor:decisionHandler:)is called for the redirected URL request.WKWebView'sURLproperty is then redirection URL.The
WKNavigationDelegatefunctionwebView(_:didReceiveServerRedirectForProvisionalNavigation:)is called.WKWebView'sURLproperty is the redirection URL.
(Note: On the iOS 11.0 simulator I have seen steps 3 and 4 reversed, with the URL property unchanged in webView(_:decidePolicyFor:decisionHandler:), which actually seems like a sensible ordering, but I haven't observed this on a device.)
It seems like the webView(_:didReceiveServerRedirectForProvisionalNavigation:) is built explicitly for the purpose of detecting redirects so is probably the preferred option, although the redirect could be possibly be inferred at steps 3 or 4 but only if you can be sure that there are no other causes of navigational change.
回答3:
Credits to Sven: https://forums.developer.apple.com/thread/117073
If you are facing a situation that your WebView doesn't open a PDF file or simply the url resolves to nothing, because the WebView's redirect URL doesn't come through you can use WKUIDelegate function webView(_:createWebViewWith:for:windowFeatures:) to capture the failed call and load the request again like:
extension WebViewWrapper: WKUIDelegate {
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
if navigationAction.targetFrame == nil || navigationAction.targetFrame?.isMainFrame == false {
webView.load(navigationAction.request)
}
return nil
}
}
回答4:
For me, using decidePolicyFor navigation delegate's method didn't work.
It didn't work because WKNavigationDelegate's method
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void)
will only be called when there is a full-page reload. To be able to catch all WKWebView's request URL changes, a Key-Value observer will have to be placed on the WKWebView's URL property.
First, in viewDidLoad add:
webView.addObserver(self, forKeyPath: "URL", options: .new, context: nil)
Second, add observeValue method
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == #keyPath(WKWebView.url) {
// Whenever URL changes, it can be accessed via WKWebView instance
let url = webView.url
}
}
来源:https://stackoverflow.com/questions/45604336/capture-redirect-url-in-wkwebview-in-ios