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

Mat*_*ift 16 cocoa cocoa-touch webkit swift wkwebview

不像一个UIWebView和WKWebView(iOS版10的MacOS 10.12)的早期版本中,本地文件的默认加载操作已经从移动Bundle.main.pathBundle.main.url.同样,loadFileURL也成为在WKWebView中加载本地资源的默认函数.

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

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

Mat*_*ift 47

更新了Swift 4,Xcode 9.3


此方法允许WKWebView正确读取链接的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)
    
    Run Code Online (Sandbox Code Playgroud)

解决方案(深入)

步骤1

将本地Web文件的文件夹导入到项目中的任何位置.确保你:

Xcode>文件>将文件添加到

☑️如果需要,复制项目

☑️ 创建文件夹引用 (不是"创建组")

☑️添加到目标

第2步

使用WKWebView转到View Controller并将以下代码添加到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)
Run Code Online (Sandbox Code Playgroud)
  • index- 要加载的文件的名称(不带.html扩展名)
  • website- 您的Web文件夹的名称(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)
    }

}
Run Code Online (Sandbox Code Playgroud)

如果您有任何关于此方法或代码的问题,我会尽力回答!

  • 我很困惑为什么还要调用`.load(request)`.我认为`loadFileURL()`是加载本地文件的首选方式,`load(request)`是否需要做额外的事情? (14认同)
  • 我得到:致命错误:展开一个Optional值时意外发现nil。我可以使它工作的唯一方法是,将index.html放在xcodeproj文件所在的文件夹中,并使用“ /”作为子目录 (4认同)
  • 您不需要调用“load”。只需调用“loadFileURL”即可。第二个“负载”毫无意义。 (2认同)

Zou*_*ssi 12

这项工作对我来说:

        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];
Run Code Online (Sandbox Code Playgroud)