【问题标题】:Migrating from UIWebView to WKWebView从 UIWebView 迁移到 WKWebView
【发布时间】:2016-09-27 08:35:57
【问题描述】:

在我的应用程序中,我正在从 UIWebView 迁移到 WKWebView ,如何为 WKWebView 重写这些函数?

    func webViewDidStartLoad(webView: UIWebView){}
    func webViewDidFinishLoad(webView: UIWebView){}

    func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
        print("webview asking for permission to start loading")
        if navigationType == .LinkActivated && !(request.URL?.absoluteString.hasPrefix("http://www.myWebSite.com/exemlpe"))!{
            UIApplication.sharedApplication().openURL(request.URL!)
            print(request.URL?.absoluteString)
            return false
        }
        print(request.URL?.absoluteString)
        lastUrl = (request.URL?.absoluteString)!

        return true
    }


    func webView(webView: UIWebView, didFailLoadWithError error: NSError?) {
        print("webview did fail load with error: \(error)")
        let testHTML = NSBundle.mainBundle().pathForResource("back-error-bottom", ofType: "jpg")
        let baseUrl = NSURL(fileURLWithPath: testHTML!)

        let htmlString:String! = "myErrorinHTML"
        self.webView.loadHTMLString(htmlString, baseURL: baseUrl)
    }

【问题讨论】:

标签: ios swift uiwebview wkwebview


【解决方案1】:

这是 迁移Objective-C 方法:

  1. shouldStartLoadWithRequest -> 决定PolicyForNavigationAction

记得拨打decisionHandler:

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
       if (navigationAction.navigationType == WKNavigationTypeLinkActivated) {

       }
       NSString *url = [navigationAction.request.URL query];
                
       decisionHandler(WKNavigationActionPolicyAllow);
}
  1. webViewDidStartLoad -> didStartProvisionalNavigation
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
}
  1. webViewDidFinishLoad -> didFinishNavigation
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
}
  1. didFailLoadWithError -> didFailNavigation
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
}

【讨论】:

  • 应该是WKNavigationTypeLinkActivated 而不是UIWebViewNavigationTypeLinkClicked
【解决方案2】:

UIWebView => WKWebView 等效

UIWebViewDelegate => WKNavigationDelegate

delegate => navigationDelegate
didFailLoadWithError => didFailNavigation
webViewDidFinishLoad => didFinishNavigation
webViewDidStartLoad => didStartProvisionalNavigation
shouldStartLoadWithRequest => decidePolicyForNavigationAction

关于shouldStartLoadWithRequest可以写:

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    print("webView:\(webView) decidePolicyForNavigationAction:\(navigationAction) decisionHandler:\(decisionHandler)")
    
    switch navigationAction.navigationType {
        case .linkActivated:
        if navigationAction.targetFrame == nil {
            self.webView?.loadRequest(navigationAction.request)
        }
        if let url = navigationAction.request.url, !url.absoluteString.hasPrefix("http://www.myWebSite.com/example") {
            UIApplication.shared.open(url)
            print(url.absoluteString)
            decisionHandler(.cancel)
        return
        }
        default:
            break
    }
    
    if let url = navigationAction.request.url {
        print(url.absoluteString)
    }
    decisionHandler(.allow)
}

对于didFailLoadWithError

func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
    print("webView:\(webView) didFailNavigation:\(navigation) withError:\(error)")
    let testHTML = Bundle.main.path(forResource: "back-error-bottom", ofType: "jpg")
    let baseUrl = URL(fileURLWithPath: testHTML!)

    let htmlString = "myErrorInHTML"
    self.webView.loadHTMLString(htmlString, baseURL: baseUrl)
}

【讨论】:

  • webViewDidFinishLoad 和 didFinishNavigation 并不完全相同。在页面完全加载之前调用 didFinishNavigation 方法。
  • 文档说这种方法仅适用于 osx。问题是针对 iOS 的
  • @Gargo 看看这两个描述:webViewDidFinishLoaddidFinishNavigation,正如你所见,iOS 8.0+ 也可以使用
  • stackoverflow.com/questions/46171410/… - 任何人都可以帮我解决这个问题@AlessandroOrnano
  • 请注意,这些方法是在WKNavigationDelegate(不是WKUIDelegate)中声明的。
【解决方案3】:

将 UIWebView 迁移到 WKWebView,Swift 4

相当于shouldStartLoadWithRequest

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    var action: WKNavigationActionPolicy?

    defer {
        decisionHandler(action ?? .allow)
    }

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

    print(url)

    if navigationAction.navigationType == .linkActivated, url.absoluteString.hasPrefix("http://www.example.com/open-in-safari") {
        action = .cancel                  // Stop in WebView
        UIApplication.shared.openURL(url) // Open in Safari
    }
}

等价于webViewDidStartLoad

func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
    print(String(describing: webView.url))
}

等价于didFailLoadWithError

func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
    let nserror = error as NSError
    if nserror.code != NSURLErrorCancelled {
        webView.loadHTMLString("404 - Page Not Found", baseURL: URL(string: "http://www.example.com/"))
    }
}

等价于webViewDidFinishLoad

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
    print(String(describing: webView.url))
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-12
    • 2018-09-14
    • 1970-01-01
    • 1970-01-01
    • 2020-05-10
    • 2018-02-20
    • 1970-01-01
    • 2021-04-21
    相关资源
    最近更新 更多