为什么在iOS 9中WKWebView无法打开电话链接?

3
我有一个WKWebView,它加载了一个带有一些电话链接的网页。
目前我有以下代码来处理对这些链接的点击。
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    if navigationAction.request.url?.scheme == "tel" {
        if #available(iOS 10.0, *) {
            UIApplication.shared.open(navigationAction.request.url!, options: [:], completionHandler: nil)
        } else {
            UIApplication.shared.openURL(navigationAction.request.url!)
        }
        decisionHandler(.cancel)
        return
    }
    decisionHandler(.allow)
}

这在任何安装了iOS 10的设备上都可以正常工作,我会看到一个警告框,询问是取消还是拨打电话。但是在iOS 9设备上,电话应用程序屏幕会闪烁(没有提示),之后就不会发生任何事情。

2个回答

5

在继续之前需要了解的关键概念:

默认情况下,Web视图会自动将网页内容中出现的电话号码转换为电话链接。当点击电话链接时,电话应用程序会启动并拨打该号码。在iOS设备上,使用tel URL方案启动电话应用程序并发起指定电话号码的拨号。

从HTML方面来看,显示电话号码的网页必须像这样:

<body>
     <!-- Then use phone links to explicitly create a link. -->
     <p>A phone number: <a href="tel:1-408-555-5555">1-408-555-5555</a></p>
     <!-- Otherwise, numbers that look like phone numbers are not links. -->
     <p>Not a phone number: 408-555-5555</p>
</body>

在这个简短的前言之后,WKWebView有两种行为,一种适用于iOS 9,另一种适用于iOS 10及更高版本。
在iOS 10中,苹果引入了一个名为dataDetectorTypes的属性,在WKWebViewConfiguration上,默认情况下,此属性的值为WKDataDetectorTypeNone,表示不检测任何内容。因此,如果您想检测电话号码和链接(仅作为示例),WKWebView的配置应如下所示(假设您有一个类型为WKWebView的变量_webView):


    WKWebViewConfiguration *configuration = [WKWebViewConfiguration new];
    if ([configuration respondsToSelector:@selector(dataDetectorTypes)]) {
        configuration.dataDetectorTypes = UIDataDetectorTypeLink | UIDataDetectorTypePhoneNumber;
    }

    _webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];

有了这个配置,您的webView将能够处理所有底层内容。

现在,在 iOS 9 > 且 < 10(iOS 9和10之间),您的委托决策处理程序将如下所示:



    - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {

     if ([navigationAction.request.URL.scheme isEqualToString:@"tel"]){

            [UIApplication.sharedApplication openURL:navigationAction.request.URL];

            decisionHandler(WKNavigationActionPolicyCancel);

        }else {
            decisionHandler(WKNavigationActionPolicyAllow);
        }

    }

这将打开电话应用程序。请注意:

iOS 10.3及更高版本会显示一个警报并要求用户确认才能拨打电话。(当此情况发生在iOS 10.3之前的版本中时,iOS会自动拨号并且不再提示用户或显示警报,尽管本地应用可以配置自己的警报)

请不要按照任何关于URL方案白名单的说明进行操作,这是苹果在iOS 9上引入的另一个故事,但是现在处理tel方案的工作是由iOS来完成的。

希望这可以帮到您。


对我来说运行得很好,我将其与https://gist.github.com/dakeshi/d8e69e4ba50b31211d94相结合。 - Milan Manwar

0

Swift 4:

 webView.navigationDelegate = self
 webView.configuration.dataDetectorTypes = [.link, .phoneNumber]

extension PDFWebViewController: WKNavigationDelegate {

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        if let requestUrl = navigationAction.request.url, requestUrl.scheme == "tel" {
            UIApplication.shared.open(requestUrl, options: [:], completionHandler: nil)
            decisionHandler(.cancel)

        } else {
            decisionHandler(.allow)
        }
    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接