【问题标题】:WKWebView: mailto links in html content not opening mail appWKWebView:html内容中的mailto链接未打开邮件应用程序
【发布时间】:2019-12-03 16:09:15
【问题描述】:

我创建了一个非常简单的 iOS 应用程序(Swift 5)。这只是一个 WKWebView 加载我的 PWA 网址。

除了所有<a href="mailto:name@name.com">Mail me</a> 链接外,一切正常。当我单击它们时,没有任何反应,我的邮件应用程序没有打开。

这是我ViewController.swift的代码:

//
//  ViewController.swift
//  panel
//
//  Created by kevin on 25/07/2019.
//  Copyright © 2019 umono. All rights reserved.
//

import UIKit
import WebKit

class ViewController: UIViewController, WKUIDelegate {
    
    var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let myURL = URL(string:"https://someUrlToMyApp.appspot.com")
        let myRequest = URLRequest(url: myURL!)
        webView.load(myRequest)
        
        if #available(iOS 11.0, *) {
            webView.scrollView.contentInsetAdjustmentBehavior = .never;
        }
        
    }
    
    override func loadView() {
        
        let webConfiguration = WKWebViewConfiguration()
        webConfiguration.dataDetectorTypes = [.all]
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        view = webView
        
    }

}

编辑:

谢谢,这是我的工作代码:

//
//  ViewController.swift
//  panel
//
//  Created by kevin on 25/07/2019.
//  Copyright © 2019 umono. All rights reserved.
//

import UIKit
import WebKit

class ViewController: UIViewController, WKUIDelegate {
    
    var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let myURL = URL(string:"https://someUrlToMyApp.appspot.com")
        let myRequest = URLRequest(url: myURL!)
        webView.load(myRequest)
        
        if #available(iOS 11.0, *) {
            webView.scrollView.contentInsetAdjustmentBehavior = .never;
        }
        
        webView.navigationDelegate = self
        
    }
    
    override func loadView() {
        
        let webConfiguration = WKWebViewConfiguration()
        webConfiguration.dataDetectorTypes = [.all]
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        view = webView
        
    }

}

extension ViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction,
                 decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        guard
            let url = navigationAction.request.url else {
                decisionHandler(.cancel)
                return
        }
        
        let string = url.absoluteString
        if (string.contains("mailto:")) {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
            decisionHandler(.cancel)

            return
        }
        decisionHandler(.allow)
    }
}

【问题讨论】:

  • 设备设置中有邮件设置吗?
  • 你是在模拟器上还是在真机上?
  • 你的意思是在我自己的 iPhone 设备中?或者这是我的 IOS 应用项目中的设置?
  • 我在真实设备上
  • @kevinius 在真实设备中在 safari 中打开此页面并点击 Mail Me。如果它没有打开电子邮件编辑器,请转到设备设置并检查邮件是否已配置。

标签: ios swift wkwebview progressive-web-apps mailto


【解决方案1】:

实现您想要的一种方法是实现 WKNavigationDelegate:

import UIKit
import WebKit

class ViewController: UIViewController {

    @IBOutlet weak var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        guard
            let file = Bundle.main.path(forResource: "test", ofType: "html"),
            let html = try? String(contentsOfFile: file) else {
                return
        }

        webView.navigationDelegate = self
        webView.loadHTMLString(html, baseURL: nil)
    }

    @IBAction func didTapButton(_ sender: Any) {
        let email = "email@email.com"
        guard
            let url = URL(string: "mailto:\(email)") else {
                return
        }

        UIApplication.shared.open(url, options: [:], completionHandler: nil)
    }
}

extension ViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction,
                 decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        guard
            let url = navigationAction.request.url,
            let scheme = url.scheme else {
                decisionHandler(.cancel)
                return
        }

        if (scheme.lowercased() == "mailto") {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
            // here I decide to .cancel, do as you wish
            decisionHandler(.cancel)
            return
        }
        decisionHandler(.allow)
    }
}

这里有一个 ViewController,它有 webView 作为出口,这个 WKWebView 会加载一个像这样的 html 文件:

<a href="mailto:email@email.com">Mail me</a>

我还在情节提要中添加了一个按钮仅供参考,该按钮将具有上述 IBAction didTapButton

这里的关键是:

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

这将为您提供 URL,并让您决定适合它的策略。在这里,我检查它是否包含 mailto:,因为我已经知道这是您感兴趣的内容,所以如果它包含,我只需打开 URL,就像用户按下屏幕上可见的 UIButton 一样。

希望对你有帮助,干杯!

LE:确保你在真实设备上运行(模拟器没有安装邮件应用程序),同时确保你安装了邮件应用程序,因为我没有......

【讨论】:

  • 嗨,谢谢...我尝试添加您的代码(func webView),但这并没有改变任何东西。我还在 if (string.contains("mailto:")) 下方添加了一个 print('test') 以查看当我单击 mailto 链接时代码是否执行,但控制台中没有打印任何内容。
  • @kevinius 你设置webView.navigationDelegate = self了吗?
  • 更新了我的原始帖子以包含完整的工作解决方案
  • 但是如果您的 url 在 url 字符串中的任何位置包含 mailto 字符串,此方法将失败。例如:https://abcmailto.com,会根据情况在应用外打开。所以最好匹配url.scheme而不是contains函数。
  • @TheTiger 你是对的,但是@kevinius 应该决定在邮件应用程序打开后应该执行什么策略,我决定.cancel
猜你喜欢
  • 2015-08-02
  • 1970-01-01
  • 1970-01-01
  • 2013-10-31
  • 1970-01-01
  • 1970-01-01
  • 2012-07-30
  • 2013-08-30
  • 2016-10-02
相关资源
最近更新 更多