Le lancement de liens de téléphone/email/carte dans WKWebView

KINWebBrowser est un module de navigateur Web open source pour les applications iOS. J'ai récemment mis à jour KINWebBrowser à utiliser WKWebView commencer à supprimer progressivement UIWebView. Il en résulte des améliorations significatives, mais:

problème: WKWebView ne permet pas aux utilisateurs de lancer des liens contenant des URLs pour les numéros de téléphone, adresse e-mail, cartes, etc.

Comment puis-je configurer un WKWebView pour lancer les comportements iOS standard pour ces URLs alternatives lorsqu'il est lancé sous liens à partir de la page affichée?

tout le le code est disponible ici

Plus d'infos sur WKWebKit

voir le question sur le KINWebBrowser GitHub ici

16
demandé sur dfmuir 2014-10-22 10:01:29

6 réponses

j'ai réussi à le faire fonctionner pour le lien Google Maps (qui semble lié à la cible="_blank") et pour le schéma tel: en ajoutant cette fonction à votre KINWebBrowserViewController.m

- (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);
}
23
répondu Darren Ehlers 2014-10-23 12:57:14

fonctionne sur Xcode 8.1, Swift 2.3.

Pour target="_blank", numéro de téléphone (tél.:) et mail (mailto:) liens.

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)
    }
}
9
répondu Victor Almeida 2016-11-22 13:48:12

vous devez implémenter un autre rappel pour obtenir ce droit (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.startsWith("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.startsWith("mailto:"):
    if UIApplication.shared.canOpenURL(failingUrl) {
      UIApplication.shared.openURL(failingUrl)
      return
    }

  // Needed to open Appstore-App
  case _ where failingUrlStr.startsWith("itmss://itunes.apple.com/"):
    if UIApplication.shared.canOpenURL(failingUrl) {
      UIApplication.shared.openURL(failingUrl)
      return
    }

  default: break
  }
}

Maintenant Facebook, Mail, Appstore,.. se faire appeler directement à partir de votre application sans avoir besoin D'ouvrir Safari

5
répondu 2h4u 2017-03-28 09:21:07

cela m'aide pour Xcode 8 WKWebview

func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration, for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
    if navigationAction.targetFrame == nil {
        let url = navigationAction.request.url
        if url?.description.range(of: "http://") != nil || url?.description.range(of: "https://") != nil || url?.description.range(of: "mailto:") != nil || url?.description.range(of: "tel:") != nil  {
            UIApplication.shared.openURL(url!)
        }
    }
    return nil
}

EDITED:

Dans le lien doit être l'attribut target="_blank".

1
répondu Abduhafiz 2016-10-03 09:06:42

je suis atterri ici à la recherche de comment ouvrir gmail pièces jointes sur wkwebview.

ma solution est simple:

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    if navigationAction.targetFrame == nil, let redirect = navigationAction.request.url {
        if UIApplication.shared.canOpenURL(redirect) {
            self.webViewMail?.load(navigationAction.request)
            decisionHandler(.cancel)
            return
        }
    }
    decisionHandler(.allow)
}
1
répondu Luca Davanzo 2018-04-11 13:15:31

ci-dessus la réponse fonctionne pour moi, mais j'en avais besoin pour réécrire pour swift 2.3

if navigationAction.targetFrame == nil {
    let url = navigationAction.request.mainDocumentURL
    if url?.description.rangeOfString("mailto:")?.startIndex != nil ||
        url?.description.rangeOfString("tel:")?.startIndex != nil
    {
        if #available(iOS 10, *) {
            UIApplication.sharedApplication().openURL(url!,options: [:], completionHandler: nil)
        } else {
            UIApplication.sharedApplication().openURL(url!)  // deprecated
        }
    }
}
0
répondu Philipp Homann 2016-11-07 13:00:40