在 WKWebView 中加载本地 Web 文件和资源

Load local web files & resources in WKWebView

与 UIWebView 和以前版本的 WKWebView(iOS 10 和 macOS 10.12)不同,本地文件的默认加载操作已从 Bundle.main.path 移动到 Bundle.main.url。同样,loadFileURL也成为WKWebView默认加载本地资源的函数

我知道 .path.url 是完全不同的,并且在过去都有效 – .path 一直是默认选择的方法;然而,似乎 Swift 的最新版本已经破坏了大多数(如果不是全部的话).path 解决方案。 .path 解决方案现在似乎 扁平化 目录层次结构,将所有 CSS、JS 和任何其他子目录内容放入一个大目录中。这会在 WKWebView 尝试加载 index.html 时导致加载错误,例如,使用链接的子文件夹样式表(即 /css/style.css)。

在看到无数问题和无数 uncertain/broken 答案匹配后,是否有一个快速而轻松的解决方案来实现可以加载本地资源(包括链接的 CSS/JS 文件)的 WKWebView,而无需任何变通方法?

更新为 Swift 4,Xcode 9.3


此方法允许 WKWebView 正确读取您的目录层次结构和 sub-directories 链接的 CSS、JS 和大多数其他文件。您 不需要 更改您的 HTML、CSS 或 JS 代码。

解决方案(快速)

  1. 将 web 文件夹添加到您的项目(文件 > 将文件添加到项目)
    • 根据需要复制项目
    • 创建文件夹引用 *
    • 添加到目标(适用的)
  2. 将以下代码添加到 viewDidLoad 并根据您的需要对其进行个性化设置:

    let url = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "website")!
    webView.loadFileURL(url, allowingReadAccessTo: url)
    let request = URLRequest(url: url)
    webView.load(request)
    

解决方案(In-Depth)

第 1 步

将本地网络文件的文件夹导入到您的项目中。确保您:

☑️ Copy items if needed

☑️ Create folder references (not "Create groups")

☑️ Add to targets

第 2 步

使用 WKWebView 转到视图控制器并将以下代码添加到 viewDidLoad 方法:

let url = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "website")!
webView.loadFileURL(url, allowingReadAccessTo: url)
let request = URLRequest(url: url)
webView.load(request)
  • index – 要加载的文件的名称(不带 .html 扩展名)
  • website – 您的网络文件夹的名称(index.html 应该位于该目录的根目录)

结论

整体代码应如下所示:

import UIKit
import WebKit

class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {

    @IBOutlet weak var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()

        webView.uiDelegate = self
        webView.navigationDelegate = self

        let url = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "Website")!
        webView.loadFileURL(url, allowingReadAccessTo: url)
        let request = URLRequest(url: url)
        webView.load(request)
    }

}

如果大家对这个方法或者代码还有什么问题,我会尽力解答的!

这项工作适合我:

        WKWebView *wkwebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768)];
        wkwebView.navigationDelegate = self;
        wkwebView.UIDelegate = self;
        [wkwebView.configuration.preferences setValue:@"TRUE" forKey:@"allowFileAccessFromFileURLs"];
        NSURL *url = [NSURL fileURLWithPath:YOURFILEPATH];
        [wkwebView loadFileURL:url allowingReadAccessToURL:url.URLByDeletingLastPathComponent];
        [self.view addSubview:wkwebView];

我遇到了同样的问题,我正在下载一些 HTML 从服务器获取内容并保存到Document目录下 在应用程序中显示它。同一控制器使用 LIVE URL 我还必须将条件与 url 方案放在一起。 测试于 iOS 13 Xcode 11

  if Url.scheme == "file" as String {
         wkWebView.loadFileURL(Url, allowingReadAccessTo: Url)
    }
    else {
         let request = URLRequest.init(url: Url, cachePolicy:.reloadIgnoringLocalCacheData, timeoutInterval:60)
         wkWebView.load(request)
    }

它非常适合我

1,打开项目设置并进入构建阶段选项卡,打开 Link 带库的二进制文件。添加 Webkit 框架。

2,将 html 添加到您的项目(如果需要,复制项目)

3,将此添加到您的代码中: @IBOutlet weak var webView: WKWebView!

4、viewDidLoad viewDidLoad

可以使用您项目中的资源,甚至可以在 html 代码中使用 WKWebView 中的共享库。
例如,我展示了如何从包含 ResourceContainingBundleClassNamed class.

的包中加载 pic.png
NSSTring * htmlCode = @"<img src='pic.png'>";
NSBundle * bundle = [NSBundle bundleForClass:[ResourceContainingBundleClassNamed class]];
NSURL * base = bundle.resourceURL;
WKWebView * represent = [WKWebView new];
[represent loadHtmlString: htmlCode baseURL: base];

魔法在 resourceURL 捆绑包 属性 中。如果您只是获取所需文件的路径,则将其转换为 URL - 没有成功。