从 iOS 更改托管在 WebKit 中的网站页面

Changing pages of a website hosted in WebKit from iOS

我正在使用 Swift 3 和 WebKit 为 iOS 创建一个应用程序,该应用程序 运行 与 HTML、CSS 和 JS 不同。我的问题是,当我单击页面上的 link 以更改为不同的 HTML 文件时,没有任何反应。这是我的 ViewController:

代码
import UIKit
import WebKit

class ViewController: UIViewController {
    @IBOutlet weak var webView: WKWebView!
    override func viewDidLoad() {
        super.viewDidLoad()

        let page = Bundle.main.path(forResource: "HTML/index", ofType: "html")!
        var content: String?
        do {
            content = try String(contentsOfFile: page, encoding: 
String.Encoding.utf8)
        } catch let error as NSError {
            print("error: \(error)")
        }

        let base = Bundle.main.path(forResource: "HTML/main", ofType: "css")!
        let baseUrl = URL(fileURLWithPath: base)
        webView.loadHTMLString(content!, baseURL: baseUrl)
    }
}

这是我的 index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Opus</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
    <link rel="stylesheet" href="main.css">
</head>

<body>
    <div id="mySidenav" class="sidenav">
        <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">&times;</a>
        <a class="activeNav" href="/index.html">Home</a>
        <a href="#">Services</a>
        <a href="/settings.html">Settings</a>
        <a href="https://opus.com/help" target="_blank">Help</a>
    </div>
    <span onclick="openNav()">&#124;&#124;&#124;</span>
    <div id="main">
        <div id="header"> Opus </div>
        <img src="google.png">
    </div>
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>
    <script src="main.js"></script>
</body>

</html>

如果 <a href="/settings.html">Settings</a> 是您尝试单击的 link,则在托管网页中 href 解析为 <domain>/settings.html。但由于这都是本地的,没有域,因此无法正确解析。但是,完整路径也不起作用,因为在模拟器中提供 macOS 路径会抱怨它无法加载本地文件,而在 phone 中它甚至无法访问该文件。您应该做的是使用 javascript 桥和 WKScriptMessageHandler 将此消息传递给本机代码,并让本机部分处理加载 settings.html 页面。例如:

func viewDidLoad{
  ....
  weak var weakSelf = self //To avoid leaking memory
  self.webView.configuration.userContentController.add(weakSelf, name: "MyMessageHandler")
 ...
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
   if message.name == "MyMessageHandler"{
      if message.body == "openSettings",let settingsURL = Bundle.main.url(forResource: "HTML/settings", withExtension: "html"){
         self.webView.load(URLRequest(url:settingsURL)) //You can load it the way you did it in your question if you want css too.
      }
   }
}

在你的index.html中:

<a href="javascript:void(0)" onclick="openSettings()">Settings</a>
<script>
func openSettings(){
   window.webkit.messageHandlers.MyMessageHandler.postMessage("openSettings");
}
</script>