WKWebView无法在iOS 8下加载本地文件

Lim*_*ean 119 ios swift ios8 wkwebview

对于以前的iOS测试版8,负荷(束)本地web应用程序,它都为正常工作UIWebViewWKWebView,我甚至移植使用新的网页游戏WKWebViewAPI.

var url = NSURL(fileURLWithPath:NSBundle.mainBundle().pathForResource("car", ofType:"html"))

webView = WKWebView(frame:view.frame)
webView!.loadRequest(NSURLRequest(URL:url))

view.addSubview(webView)
Run Code Online (Sandbox Code Playgroud)

但在测试版4中,我只是得到了一个空白的白色屏幕(UIWebView仍在工作),看起来没有任何内容被加载或执行.我在日志中看到一个错误:

无法为其创建沙箱扩展 /

有没有帮助引导我走向正确的方向?谢谢!

nac*_*o4d 101

他们终于解决了这个错误!现在我们可以使用了-[WKWebView loadFileURL:allowingReadAccessToURL:].显然,这个修复在WWDC 2015视频中值得花几秒钟.介绍Safari View Controller

https://developer.apple.com/videos/wwdc/2015/?id=504

适用于iOS8~iOS10(Swift 3)

正如Dan Fabulish的回答所说,这是WKWebView的一个错误,显然很快就没有解决,因为他说有一个解决办法:)

我的回答只是因为我想在这里展示解决方法.https://github.com/shazron/WKWebViewFIleUrlTest中显示的IMO代码充满了大多数人可能不感兴趣的无关细节.

解决方法是包含20行代码,包含错误处理和注释,不需要服务器:)

func fileURLForBuggyWKWebView8(fileURL: URL) throws -> URL {
    // Some safety checks
    if !fileURL.isFileURL {
        throw NSError(
            domain: "BuggyWKWebViewDomain",
            code: 1001,
            userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("URL must be a file URL.", comment:"")])
    }
    try! fileURL.checkResourceIsReachable()

    // Create "/temp/www" directory
    let fm = FileManager.default
    let tmpDirURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("www")
    try! fm.createDirectory(at: tmpDirURL, withIntermediateDirectories: true, attributes: nil)

    // Now copy given file to the temp directory
    let dstURL = tmpDirURL.appendingPathComponent(fileURL.lastPathComponent)
    let _ = try? fm.removeItem(at: dstURL)
    try! fm.copyItem(at: fileURL, to: dstURL)

    // Files in "/temp/www" load flawlesly :)
    return dstURL
}
Run Code Online (Sandbox Code Playgroud)

并可用作:

override func viewDidLoad() {
    super.viewDidLoad()
    var fileURL = URL(fileURLWithPath: Bundle.main.path(forResource:"file", ofType: "pdf")!)

    if #available(iOS 9.0, *) {
        // iOS9 and above. One year later things are OK.
        webView.loadFileURL(fileURL, allowingReadAccessTo: fileURL)
    } else {
        // iOS8. Things can (sometimes) be workaround-ed
        //   Brave people can do just this
        //   fileURL = try! pathForBuggyWKWebView8(fileURL: fileURL)
        //   webView.load(URLRequest(url: fileURL))
        do {
            fileURL = try fileURLForBuggyWKWebView8(fileURL: fileURL)
            webView.load(URLRequest(url: fileURL))
        } catch let error as NSError {
            print("Error: " + error.debugDescription)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 仅适用于简单的网站.如果您使用ajax或通过angular加载本地视图,则期望"仅支持HTTP的交叉源请求".您唯一的后备是本地网络服务器方法,我不喜欢它,因为它在本地网络上可见.这需要注意在帖子中,节省民间几个小时. (3认同)
  • 它的一些修改,以复制整个文件夹,图像和所有.`让orgFolder = NSBundle.mainBundle().resourcePath!+"/ www"; var newFilePath = pathForBuggyWKWebView(orgFolder)self.loadingWebView!.loadRequest(NSURLRequest(URL:NSURL.fileURLWithPath(newFilePath!+"/ Loading.html")!))` (2认同)
  • 谢谢@ nacho4d.tldr;/tmp文件夹解决方案不适用于8.0,但将在8.0.2上运行.我无法让这个解决方案在我的测试设备上工作,并最终克隆了shazron的repo以试一试.那也行不通.事实证明,shazron的解决方案不适用于我的设备在iPhone 6 Plus上运行8.0(12A366)的iOS版本.我在运行iOS 8.0.2的设备(iPad Mini)上试过它,它运行正常. (2认同)

Dan*_*ich 83

WKWebView无法通过其loadRequest:方法从文件:URL加载内容.http://www.openradar.me/18039024

您可以通过加载内容loadHTMLString:,但如果您的baseURL是文件:URL,那么它仍然无法正常工作.

iOS 9有一个新的API可以满足您的需求 [WKWebView loadFileURL:allowingReadAccessToURL:].

有针对iOS 8一种变通方法,通过shazron在Objective-C证明这里https://github.com/shazron/WKWebViewFIleUrlTest将文件复制到/tmp/www并从那里加载它们.

如果你在Swift工作,你可以试试nachos4d的样本.(它也比shazron的样本短得多,所以如果你在使用shazron的代码时遇到麻烦,那就试试吧.)

  • 8.1中没有修复. (6认同)
  • 8.3它还没有固定......? (2认同)

Mar*_* T. 8

iOS 9上如何使用[WKWebView loadFileURL:allowsReadAccessToURL:]的示例.

将Web文件夹移动到项目时,选择"创建文件夹引用"

在此输入图像描述

然后使用类似这样的代码(Swift 2):

if let filePath = NSBundle.mainBundle().resourcePath?.stringByAppendingString("/WebApp/index.html"){
  let url = NSURL(fileURLWithPath: filePath)
  if let webAppPath = NSBundle.mainBundle().resourcePath?.stringByAppendingString("/WebApp") {
    let webAppUrl = NSURL(fileURLWithPath: webAppPath, isDirectory: true)
    webView.loadFileURL(url, allowingReadAccessToURL: webAppUrl)
  }
}
Run Code Online (Sandbox Code Playgroud)

在html文件中使用像这样的文件路径

<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
Run Code Online (Sandbox Code Playgroud)

不喜欢这个

<link href="/bootstrap/css/bootstrap.min.css" rel="stylesheet">
Run Code Online (Sandbox Code Playgroud)

移动到xcode项目的目录示例.

在此输入图像描述


Eth*_*anB 5

临时解决方法:我正在使用GuidoMB建议的GCDWebServer.

我首先找到捆绑的"www /"文件夹的路径(其中包含"index.html"):

NSString *docRoot = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html" inDirectory:@"www"].stringByDeletingLastPathComponent;
Run Code Online (Sandbox Code Playgroud)

...然后像这样启动它:

_webServer = [[GCDWebServer alloc] init];
[_webServer addGETHandlerForBasePath:@"/" directoryPath:docRoot indexFilename:@"index.html" cacheAge:3600 allowRangeRequests:YES];
[_webServer startWithPort:port bonjourName:nil];
Run Code Online (Sandbox Code Playgroud)

要阻止它:

[_webServer stop];
_webServer = nil;
Run Code Online (Sandbox Code Playgroud)

性能似乎很好,即使在iPad 2上也是如此.


我做了应用程序进入后台后发现崩溃,所以我就停止applicationDidEnterBackground:applicationWillTerminate:; 我启动/重新启动它的application:didFinishLaunching...applicationWillEnterForeground:.


nul*_*ube 5

[configuration.preferences setValue:@"TRUE" forKey:@"allowFileAccessFromFileURLs"];
Run Code Online (Sandbox Code Playgroud)

这为我解决了问题 iOS 8.0+ dev.apple.com

这似乎也工作得很好......

NSString* FILE_PATH = [[[NSBundle mainBundle] resourcePath]
                       stringByAppendingPathComponent:@"htmlapp/FILE"];
[self.webView
    loadFileURL: [NSURL fileURLWithPath:FILE_PATH]
    allowingReadAccessToURL: [NSURL fileURLWithPath:FILE_PATH]
];
Run Code Online (Sandbox Code Playgroud)


小智 -1

尝试使用

[webView loadHTMLString:htmlFileContent baseURL:baseURL];
Run Code Online (Sandbox Code Playgroud)

看来它仍然有效。然而。

  • 这仅适用于 HTML 文件本身,不适用于资源,对吗? (3认同)