2014-10-22 2 views
10

KINWebBrowser è un modulo browser Web open source per app iOS. Ho recentemente aggiornato KINWebBrowser per utilizzare WKWebView per iniziare a eliminare gradualmente UIWebView. Questo produce miglioramenti significativi, ma:Avvio di collegamenti telefono/email/mappa in WKWebView

Problema: WKWebView non consente agli utenti di lanciare i collegamenti contenenti URL per i numeri di telefono, indirizzo e-mail, mappe, ecc

Come posso configurare un WKWebView per lanciare iOS standard di comportamenti per questi URL alternativi quando vengono lanciati come link dalla pagina visualizzata?

Tutto il code is available here

Maggiori informazioni WKWebKit

Vedere la issue on the KINWebBrowser GitHub here

+1

Non puoi farlo. Se questa funzionalità è importante per te, questo sarebbe un motivo per rimanere attaccato a UIWebView per ora - e per presentare una richiesta di miglioramento con Apple. Ci sono un _lot_ di cose che UIWebView può fare che WKWebView non può fare. – matt

risposta

18

ero in grado di farlo funzionare per il link di Google Maps (che sembra essere correlato al target = "_blank") e per il tel: schema aggiungendo questa funzione al tuo 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); 
} 
+2

Questo codice è un po 'prolisso e non garantisce che venga chiamato 'decisionHandler'. –

+0

Buon punto! Grazie. Questa era una tarda notte, patch dell'ultimo minuto da 2 diverse fonti gettate insieme per risolvere rapidamente un problema. Mentre funzionava, non era il più pulito e c'erano sicuramente casi in cui decisionHandler non veniva chiamato. Ho modificato il codice. Grazie! –

+2

Questo codice è decisamente sulla strada giusta ma introduce una vulnerabilità di sicurezza che potrebbe consentire l'avvio involontario di chiamate e chiamate FaceTime. Controlla la mia spiegazione qui: https://github.com/dfmuir/KINWebBrowser/issues/10 – dfmuir

1

Questo mi aiuta per 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 
} 

CURA:

In collegamento deve essere attributo target="_blank".

0

Sopra workes risposta per me, ma avevo bisogno di riscrivere per 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 
     } 
    } 
} 
5

Opere su Xcode 8.1, Swift 2.3.

Per target = "_ blank", numero di telefono (tel :) e email (mailto :) link.

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) 
    } 
} 
+0

Non dimenticare di aggiungere delegato: WKUIDelegate e var webView = WKWebView() alle proprietà –

4

È necessario implementato un altro callback per ottenere questo diritto (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 
    } 
} 

Ora Facebook, posta, Appstore, .. sempre chiamato direttamente dalla tua app, senza la necessità di aprire Safari