在WKWebView中启动电话/电子邮件/地图链接

dfm*_*uir 18 cocoa objective-c ios wkwebview

KINWebBrowser是一个用于iOS应用程序的开源Web浏览器模块.我最近升级了KINWebBrowser以使用WKWebView开始逐步淘汰UIWebView.这会带来显着的改善,但是:

问题:WKWebView不允许用户启动包含电话号码,电子邮件地址,地图等URL的链接.

如何从显示的页面中作为链接启动时,如何配置WKWebView以启动这些备用URL的标准iOS行为?

所有代码都可以在这里找到

有关WKWebKit的更多信息

请在此处查看KINWebBrowser GitHub上问题

Dar*_*ers 24

我能够通过将此函数添加到您的KINWebBrowserViewController.m来使其适用于Google Maps链接(似乎与target ="_ blank"相关)和tel:scheme

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
    if(webView != self.wkWebView) {
        decisionHandler(WKNavigationActionPolicyAllow);
        return;
    }

    UIApplication *app = [UIApplication sharedApplication];
    NSURL         *url = navigationAction.request.URL;

    if (!navigationAction.targetFrame) {
        if ([app canOpenURL:url]) {
            [app openURL:url];
            decisionHandler(WKNavigationActionPolicyCancel);
            return;
        }
    }
    if ([url.scheme isEqualToString:@"tel"])
    {
        if ([app canOpenURL:url])
        {
            [app openURL:url];
            decisionHandler(WKNavigationActionPolicyCancel);
            return;
        }
    }
    decisionHandler(WKNavigationActionPolicyAllow);
}
Run Code Online (Sandbox Code Playgroud)

  • 这段代码有点冗长,并不保证调用`decisionHandler`. (2认同)
  • 这段代码肯定是在正确的道路上,但它引入了一个安全漏洞,可能允许不情愿地启动呼叫和FaceTime呼叫.在这里查看我的解释:https://github.com/dfmuir/KINWebBrowser/issues/10 (2认同)
  • 好方案! (2认同)
  • 为避免@dfmuir指出的安全漏洞问题,请将URL更改为"telprompt"而不是默认的"tel".例如,如果原始自定义URL为"tel:(212)%20555-6666",则telprompt等效项为"telprompt:(212)%20555-6666".这样,用户在拨打电话之前会收到提示 (2认同)

小智 10

适用于xcode 8.1,Swift 2.3.

对于target ="_ blank",电话号码(tel :)和电子邮件(mailto :)链接.

func webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) {
    if webView != self.webview {
        decisionHandler(.Allow)
        return
    }

    let app = UIApplication.sharedApplication()
    if let url = navigationAction.request.URL {
        // Handle target="_blank"
        if navigationAction.targetFrame == nil {
            if app.canOpenURL(url) {
                app.openURL(url)
                decisionHandler(.Cancel)
                return
            }
        }

        // Handle phone and email links
        if url.scheme == "tel" || url.scheme == "mailto" {
            if app.canOpenURL(url) {
                app.openURL(url)
                decisionHandler(.Cancel)
                return
            }
        }

        decisionHandler(.Allow)
    }
}
Run Code Online (Sandbox Code Playgroud)

更新为swift 4.0

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

    if webView != self.webView {
        decisionHandler(.allow)
        return
    }

    let app = UIApplication.shared
    if let url = navigationAction.request.url {
        // Handle target="_blank"
        if navigationAction.targetFrame == nil {
            if app.canOpenURL(url) {
                app.open(url)
                decisionHandler(.cancel)
                return
            }
        }

        // Handle phone and email links
        if url.scheme == "tel" || url.scheme == "mailto" {
            if app.canOpenURL(url) {
                app.open(url)
            }

            decisionHandler(.cancel)
            return
        }

        decisionHandler(.allow)
    }

}
Run Code Online (Sandbox Code Playgroud)


2h4*_*h4u 7

你需要实现另一个回调才能做到这一点(Swift 3.1):

// Gets called if webView cant handle URL
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
  guard let failingUrlStr = (error as NSError).userInfo["NSErrorFailingURLStringKey"] as? String  else { return }
  let failingUrl = URL(string: failingUrlStr)!

  switch failingUrl {
    // Needed to open Facebook
    case _ where failingUrlStr.hasPrefix("fb:"):
    if #available(iOS 10.0, *) {
       UIApplication.shared.open(failingUrl, options: [:], completionHandler: nil)
       return
    } // Else: Do nothing, iOS 9 and earlier will handle this

  // Needed to open Mail-app
  case _ where failingUrlStr.hasPrefix("mailto:"):
    if UIApplication.shared.canOpenURL(failingUrl) {
      UIApplication.shared.open(failingUrl, options: [:], completionHandler: nil)
      return
    }

  // Needed to open Appstore-App
  case _ where failingUrlStr.hasPrefix("itmss://itunes.apple.com/"):
    if UIApplication.shared.canOpenURL(failingUrl) {
      UIApplication.shared.open(failingUrl, options: [:], completionHandler: nil)
      return
    }

  default: break
  }
}
Run Code Online (Sandbox Code Playgroud)

现在Facebook,Mail,Appstore,...直接从你的应用程序调用,而无需打开Safari