设备上的 WKWebView 无法加载缓存 HTML

WKWebView on device can't load cached HTML

我有一个在模拟器中完美运行的 WKWebView 但为什么在设备中运行时只出现一个白色的空白屏幕这是我的代码:

override func loadView() {
    let webConfiguration = WKWebViewConfiguration()
    webConfiguration.preferences.setValue(true, forKey:"allowFileAccessFromFileURLs")
    webView = WKWebView(frame: .zero, configuration: webConfiguration)
    webView.uiDelegate = self
    view = webView
}

override func viewDidLoad() {
    super.viewDidLoad()

    let path2Esferas = Path.localPath.stringByAppendingPathComponent(path: "\(Path.DIR_IMAGES)\(ImagenDescargaTipo.esfera.rawValue)/\(desarrollo.id)/virtualtour.html")
    let url =  URL(fileURLWithPath: path2Esferas) 
    //NSURL.fileURL(withPath: path2Esferas)

    let myRequest = URLRequest(url: url)
    webView.load(myRequest)
}

"path2Esferas" 中的 HTML 位于我之前加载的缓存文件夹中,如果我将 let myURL = URL(string: "https://www.apple.com") 之类的 URL 与 docs show, it works correctly in simulator and device. Eg: http://proyectoshm.com/esferas/real_de_mina/realdeminas.html

简介

我的解决方案不是解决全部问题。

我暂时把它留在这里可能有助于理解(主要来自我们下面的评论)什么不起作用。


import UIKit
import WebKit

class ViewController: UIViewController {
  var webView:WKWebView?

  override func viewDidLoad() {
    super.viewDidLoad()

    let webConfiguration = WKWebViewConfiguration()
    self.webView = WKWebView(frame: self.view.frame, configuration: webConfiguration)
    // http request with URLRequest.CachePolicy.returnCacheDataElseLoad
    let request = URLRequest(url: URL(string:"http://proyectoshm.com/esferas/real_de_mina/realdeminas.html")!, cachePolicy: URLRequest.CachePolicy.returnCacheDataElseLoad, timeoutInterval: 10)
    self.webView?.load(request)
    self.view.addSubview(self.webView!)
  }
}

我也加入了plist:

App Transport Security Settings > Allow Arbitrary Loads in Web Content > YES App Transport Security Settings > Allow Arbitrary Loads > YES

最终要能够在商店中提交您的应用程序,您会遇到一些麻烦,因为:

Apple announced that ATS will be REQUIRED of all apps as of January 2017.

https://forums.developer.apple.com/thread/48979

结果是:

问题是这个短语:

frame: .zero

提供一些框架,即使它是一个虚拟值:

frame: CGRect(x:0, y:0, width:100, height:100)

如果我从评论和您的代码中了解到(Path.localPath 应该与您的本地资源相关..),您必须处理本地文件。我记得应该和你把本地资源加载到WkWebView的方法不对有关。事实上,由于 iOS 9.0+,正如对 docs 的解释,您可以使用实例方法 loadFileURL(_:allowingReadAccessTo:)

你也应该试试 loadHTMLString:

let path2Esferas = Path.localPath.stringByAppendingPathComponent(path: "\(Path.DIR_IMAGES)\(ImagenDescargaTipo.esfera.rawValue)/\(desarrollo.id)/virtualtour.html")
let folderPath = Path.localPath.stringByAppendingPathComponent(path: "\(Path.DIR_IMAGES)\(ImagenDescargaTipo.esfera.rawValue)/\(desarrollo.id)")
let baseUrl = URL(fileURLWithPath: folderPath, isDirectory: true)
do {
     let htmlString = try NSString(contentsOfFile: htmlPath!, encoding: String.Encoding.utf8.rawValue)
     webView.loadHTMLString(htmlString as String, baseURL: baseUrl)
} catch {
  // catch error
}

P.S. 确保您的本地 html/JavaScript/CSS 文件添加到 Project -> 目标 -> 构建阶段 -> 复制捆绑资源

无论如何,请记住只有在下载完成后才能加载本地资源,因此如果您有异步下载,请确保您已完成下载以使用此代码。

不要通过设置私有 API 标志 allowFileAccessFromFileURLs 来破解 WKWebViewConfiguration,而是尝试使用特殊文件 URL 方法加载文件 URL:

self.webView?.loadFileURL(url, allowingReadAccessToURL: url.deletingLastPathComponent)

你试过换线吗

let myRequest = URLRequest(url: url)

let myRequest = URLRequest(url: url, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: 100)

请检查您的网络连接,如果您与 html 文件的网络不同,您将看不到任何内容

1 年多后我找到了解决方案,我们需要使用 loadFileURL 来访问本地资源,这是我使用 WKWebView 的工作代码,而不是加载我使用 loadHTMLString。 vistaweb 在我的 WebView 顺便说一句

感谢这个回答:

        do {

            let local = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0]
            // Loading: Library/Caches/repositorioLocal/esferas/znvUifZhH8mIDr09cX8j/index.html
            let resourceFolder = "repositorioLocal/esferas/znvUifZhH8mIDr09cX8j"
            let fileToLoad = "index.html"

            let urlToFolder = URL(fileURLWithPath: local).appendingPathComponent(resourceFolder)
            let urlToFile =  URL(fileURLWithPath: local).appendingPathComponent(resourceFolder).appendingPathComponent(fileToLoad)
            let fileContent = try String(contentsOf: urlToFile)

            let webConfiguration = WKWebViewConfiguration()
            webConfiguration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
            webConfiguration.allowsInlineMediaPlayback = true

            vistaweb = WKWebView(frame: self.view.frame, configuration: webConfiguration)
            self.vistaweb.loadFileURL(urlToFolder, allowingReadAccessTo: urlToFolder)
            self.vistaweb.loadHTMLString(fileContent, baseURL: urlToFile)
            self.view.addSubview(vistaweb)

        } catch let error {
            print("Error: \(error.localizedDescription)")
        }