如何在不允许站点时使用 decidePolicyFor 显示 UIAlertController

How to display a UIAlertController when site is not allowed, using decidePolicyFor

我正在阅读 Paul Hudson 的 Hacking 和 Swift 教程,并试图让 WebView 在不允许站点时显示 UIAlertController。现在,允许的站点来自硬编码数组。

我已经尝试在调用 decisionHandler(.cancel) 之前插入以下内容,并将其添加到 if host.contains(website) 语句的末尾:

let alert = UIAlertController(title: "Heads Up!", message: "This URL is blocked.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .cancel))
present(alert, animated: true)

代码如下:

var websites = ["apple.com", "hackingwithswift.com"]

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
     let url = navigationAction.request.url

     if let host = url?.host {
         for website in websites {
             if host.contains(website) {
                 decisionHandler(.allow)
                 return
             }
         }
     }
  decisionHandler(.cancel)
}

我知道访问者甚至只能访问两个网站 - 但如果不适用,这对 Paul 的网站来说并不是一个挑战。你可以在这里查看我这个项目的整个回购协议:https://github.com/andrewlundy/hacking-with-swift/tree/master/Project4

添加 UITableViewController 作为初始 ViewController 后,在列表中显示网站,然后检查当前站点是否在托管 [=14] 的 ViewController 中=],它的 属性 为 websites,我能够想出一个基本的解决方案。

通过在 UITableViewController 中使用 didSelectRowAt 你可以看到,如果用户点击的网站不在允许的网站中,它现在会弹出一个警告,让用户知道该站点已被阻止。

我相信这可以改进,因此您不必更新每个 ViewController 中的两个 websites 属性,但这将适用于 Swift 教程中的 Hacking。如果您可以提高效率,请添加到此答案中。

新的 TableViewController class:

class TableViewController: UITableViewController {

    let webView = ViewController()
    var websites = ["apple.com", "hackingwithswift.com", "facebook.com"]


    override func viewDidLoad() {
        super.viewDidLoad()
        print(webView.websites)
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return websites.count
    }


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "WebsiteCell", for: indexPath)
        cell.textLabel?.text = websites[indexPath.row]
        return cell
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let currentSite = websites[indexPath.row]
        webView.currentSite = currentSite

        if webView.websites.contains(currentSite) {
            navigationController?.pushViewController(webView, animated: true)
        } else {
            let alert = UIAlertController(title: "Heads Up!", message: "This URL is blocked", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { (UIAlertAction) in
                self.navigationController?.popViewController(animated: true)
            }))
            present(alert, animated: true)
        }
    }
}