Migrating UIWebView delegate to WKWebView delegate method
Solution 1
You might required to implement the following in your code, which means instead of using UIWebViewDelegate protocol try to use WKNavigationDelegate protocol. I guess you are missing one of the most important function when you are handling with sessions.
func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
print(#function)
completionHandler(.performDefaultHandling,nil)
}
There are different types of AuthChallengeDisposition , like
public enum AuthChallengeDisposition : Int {
case useCredential
case performDefaultHandling
case cancelAuthenticationChallenge
case rejectProtectionSpace
}
Complete WKNavigationDelegate protocols are
extension ViewController: WKNavigationDelegate{
func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
print(#function)
}
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
print(#function)
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
print(#function)
}
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
print(#function)
}
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
print(#function)
}
func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {
print(#function)
}
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
print(#function)
}
func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
print(#function)
completionHandler(.performDefaultHandling,nil)
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
print(#function)
decisionHandler(.allow)
}
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
print(#function)
decisionHandler(.allow)
}
}
Solution 2
I guess you can use webView(_:decidePolicyFor:decisionHandler:)
and you block/cancel or allow requests. That should work in the same way.
Disclaimer: I haven't tested that yet, I'll do so as soon as I find some time.
Solution 3
analyzing your code, i have found a statement that is never reached cause of "return" called before.
The statement is:
decisionHandler(.allow)
You can find it as last line of code for the function:
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (_: WKNavigationActionPolicy) -> Void)
that you have up this method:
func webViewDidStartLoad(_ webView: UIWebView) {
numberOfDidStartLoads += 1
}
Related videos on Youtube
Comments
-
Siva almost 2 years
I am working on migrating UIWebView to WKWebView. I have changed all the Delegate methods. I need WKWebView delegate methods equal to below UIWebView delegate method. The app is working fine. but login session is not retaining
UIWebView: extension WebViewController: UIWebViewDelegate { func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool { guard let url = request.url else { return true } guard !url.absoluteString.contains("data:application/pdf") else { navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.action, target: self, action: #selector(share(sender:))) return true } guard url.pathExtension != "pdf" else { let safariVC = SFSafariViewController(url: url) safariVC.modalPresentationStyle = .popover present(safariVC, animated: true, completion: nil) return false } guard url.isLogin() == false else { AppDelegate.navigationController.signOut(.sessionOnly) return false } guard let mobileSite = url.asMobileSite() else { return true } let mobileRedirect = URLRequest(url: mobileSite) webView.loadRequest(mobileRedirect) return false } func webViewDidStartLoad(_ webView: UIWebView) { numberOfDidStartLoads += 1 } func webViewDidFinishLoad(_ webView: UIWebView) { numberOfDidStartLoads -= 1 } func webView(_ webView: UIWebView, didFailLoadWithError error: Error) { numberOfDidStartLoads -= 1 } }
And i tried below code and getting session expire.
extension WebViewController: UIWebViewDelegate { func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (_: WKNavigationActionPolicy) -> Void) { guard let url = navigationAction.request.url else { decisionHandler(.allow) return } guard !url.absoluteString.contains("data:application/pdf") else { navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.action, target: self, action: #selector(share(sender:))) decisionHandler(.allow) return } guard url.pathExtension != "pdf" else { let safariVC = SFSafariViewController(url: url) safariVC.modalPresentationStyle = .popover present(safariVC, animated: true, completion: nil) decisionHandler(.cancel) return } guard url.isLogin() == false else { AppDelegate.navigationController.signOut(.sessionOnly) decisionHandler(.cancel) return } guard let mobileSite = url.asMobileSite() else { decisionHandler(.allow) return } let mobileRedirect = URLRequest(url: mobileSite) webView.load(mobileRedirect) decisionHandler(.cancel) return decisionHandler(.allow) } func webViewDidStartLoad(_ webView: UIWebView) { numberOfDidStartLoads += 1 } func webViewDidFinishLoad(_ webView: UIWebView) { numberOfDidStartLoads -= 1 } func webView(_ webView: UIWebView, didFailLoadWithError error: Error) { numberOfDidStartLoads -= 1 } }
Please help me to resolve this issue. I have made some mistake in changing code from UIWebView to WKWebView.
-
Tamás Sengel over 6 yearsPossible duplicate of Migrating from UIWebView to WKWebView
-
Mert Buran over 6 yearscan you give more info about the crash? you must call
decisionHandler
in this method, can the crash be related to that? -
Siva over 6 yearsNo. 'App Delegate' Crash. I have added screenshot please see @MertBuran
-
Mert Buran over 6 yearsdo you have an exception breakpoint while debugging?
AppDelegate
shouldn't be crashing here -
Siva over 6 yearsNo Exception breakpoint.
-
Siva over 6 years@MertBuran Any idea?
-
Mert Buran over 6 yearsi mean you should add an "exception breakpoint" (you can google it with these keywords) to see which line actually crashes, then you can dig deeper to fix the crash. btw, looks like your original question is answered; now you are asking another question. i'd suggest you asking another question on SO instead of merging two different questions into one. hope that helps
-
Siva over 6 yearsLet us continue this discussion in chat.
-
shallowThought over 6 yearsI do not understand the actual issue. How I understand, the app crashes in AppDelegate and you do not know why? Is this correct? Or is
session
nill at some point ("login session is not retaining")? -
Siva over 6 years@shallowThought The issue is session is not retaining.
-
-
Siva over 6 yearsI guess session is not retaining. Same thing working fine in UIWebView. Do you need more info?
-
Bhargav B. Bajani over 4 years@Siva have you got any solution for the session is not retaining?