Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/111.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
WKWebView未在iOS 8下加载本地文件_Ios_Swift_Ios8_Wkwebview - Fatal编程技术网

WKWebView未在iOS 8下加载本地文件

WKWebView未在iOS 8下加载本地文件,ios,swift,ios8,wkwebview,Ios,Swift,Ios8,Wkwebview,对于以前的iOS 8 Beta,加载一个本地web应用程序(捆绑),它对UIWebView和WKWebView都可以正常工作,我甚至使用新的WKWebViewAPI移植了一个web游戏 var url = NSURL(fileURLWithPath:NSBundle.mainBundle().pathForResource("car", ofType:"html")) webView = WKWebView(frame:view.frame) webView!.loadRequest(NSUR

对于以前的iOS 8 Beta,加载一个本地web应用程序(捆绑),它对
UIWebView
WKWebView
都可以正常工作,我甚至使用新的
WKWebView
API移植了一个web游戏

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

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

view.addSubview(webView)
但是在beta 4中,我得到了一个空白的白色屏幕(
UIWebView
仍然有效),看起来没有加载或执行任何内容。我在日志中看到一个错误:

无法为
/

有没有人能帮我找到正确的方向?谢谢

尝试使用

[webView loadHTMLString:htmlFileContent baseURL:baseURL];

看来它还在工作。然而

我正在使用下面的。有一些额外的东西我正在处理,但你可以看到我已经注释掉了loadRequest并替换了loadHTMLString调用。希望这有助于他们修复错误

import UIKit
import WebKit

class ViewController: UIViewController, WKScriptMessageHandler {

    var theWebView: WKWebView?

    override func viewDidLoad() {
        super.viewDidLoad()

        var path = NSBundle.mainBundle().pathForResource("index", ofType: "html", inDirectory:"www" )
        var url = NSURL(fileURLWithPath:path)
        var request = NSURLRequest(URL:url)
        var theConfiguration = WKWebViewConfiguration()

        theConfiguration.userContentController.addScriptMessageHandler(self, name: "interOp")

        theWebView = WKWebView(frame:self.view.frame, configuration: theConfiguration)

        let text2 = String.stringWithContentsOfFile(path, encoding: NSUTF8StringEncoding, error: nil)

        theWebView!.loadHTMLString(text2, baseURL: nil)

        //theWebView!.loadRequest(request)

        self.view.addSubview(theWebView)


    }

    func appWillEnterForeground() {

    }

    func appDidEnterBackground() {

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func userContentController(userContentController: WKUserContentController!, didReceiveScriptMessage message: WKScriptMessage!){
        println("got message: \(message.body)")

    }

}

WKWebView无法通过其
loadRequest:
方法从文件:URL加载内容

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

iOS 9有一个新的API,可以实现您想要的功能,
[WKWebView加载文件URL:allowingReadAccessToURL:

iOS 8有一个变通方法,shazron在Objective-C中对此进行了演示


如果你在Swift工作,你可以改为。(它也比shazron的示例短得多,因此如果您对shazron的代码有问题,请尝试一下。)

临时解决方法:我正在使用,正如GuidoMB所建议的那样

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

。。。然后像这样启动:

_webServer = [[GCDWebServer alloc] init];
[_webServer addGETHandlerForBasePath:@"/" directoryPath:docRoot indexFilename:@"index.html" cacheAge:3600 allowRangeRequests:YES];
[_webServer startWithPort:port bonjourName:nil];
要阻止它:

[_webServer stop];
_webServer = nil;
即使在iPad2上,性能也不错



我确实注意到应用程序进入后台后出现崩溃,所以我在
applicationIdentinterbackground:
上停止它,而
applicationWillTerminate:
;我在
应用程序:didfishLaunching…
应用程序将进入前台:

在GCDWebServer的同一行中,我使用SImpleHttpServer(),然后使用本地主机url加载请求。使用这种方法,您不必添加任何库,但网站文件不在捆绑包中,因此无法交付。因此,这将更适合于调试案例。

他们最终解决了这个bug!现在我们可以使用
-[WKWebView加载文件URL:allowingReadAccessToURL:][/code>。
显然,这一修正值得几秒钟的时间

对于iOS8~iOS10(Swift 3) 正如他所说的,这是WKWebView的一个bug,显然没有很快得到解决,他说有一个解决办法:)

我回答这个问题只是因为我想展示一下这里的工作。中显示的IMO代码充满了大多数人可能不感兴趣的无关细节

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

并可用作:

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)
        }
    }
}

我已经设法在OS X上使用PHP的web服务器。复制到临时/www目录对我不起作用。Python SimpleHTTPServer抱怨想要读取MIME类型,这可能是一个沙箱问题

下面是一个使用
php-s
的服务器:

let portNumber = 8080

let task = NSTask()
task.launchPath = "/usr/bin/php"
task.arguments = ["-S", "localhost:\(portNumber)", "-t", directoryURL.path!]
// Hide the output from the PHP server
task.standardOutput = NSPipe()
task.standardError = NSPipe()

task.launch()

除了Dan Fabulich提到的解决方案之外,还有另一种解决方法。[WKWebView loadFileURL:allowingReadAccessToURL:]是。

我还不能发表评论,所以我将此作为一个单独的答案发布

这是的objective-c版本。到目前为止,这是我见过的最好的解决方法

- (NSString *)pathForWKWebViewSandboxBugWithOriginalPath:(NSString *)filePath
{
    NSFileManager *manager = [NSFileManager defaultManager];
    NSString *tempPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"www"];
    NSError *error = nil;

    if (![manager createDirectoryAtPath:tempPath withIntermediateDirectories:YES attributes:nil error:&error]) {
        NSLog(@"Could not create www directory. Error: %@", error);

        return nil;
    }

    NSString *destPath = [tempPath stringByAppendingPathComponent:filePath.lastPathComponent];

    if (![manager fileExistsAtPath:destPath]) {
        if (![manager copyItemAtPath:filePath toPath:destPath error:&error]) {
            NSLog(@"Couldn't copy file to /tmp/www. Error: %@", error);

            return nil;
        }
    }

    return destPath;
}

@nacho4d溶液是好的。我想更改一下,但我不知道如何在你的帖子中更改。所以我把它放在这里,希望你不介意。谢谢

如果你有一个www文件夹,有许多其他文件,如png、css、js等,那么你必须将所有文件复制到tmp/www文件夹。 例如,您的www文件夹如下所示:

然后在Swift 2.0中:

override func viewDidLoad() {
    super.viewDidLoad()

    let path = NSBundle.mainBundle().resourcePath! + "/www";
    var fileURL = NSURL(fileURLWithPath: path)
    if #available(iOS 9.0, *) {
        let path = NSBundle.mainBundle().pathForResource("index", ofType: "html", inDirectory: "www")
        let url = NSURL(fileURLWithPath: path!)
        self.webView!.loadRequest(NSURLRequest(URL: url))
    } else {
        do {
            fileURL = try fileURLForBuggyWKWebView8(fileURL)
            let url = NSURL(fileURLWithPath: fileURL.path! + "/index.html")
            self.webView!.loadRequest( NSURLRequest(URL: url))
        } catch let error as NSError {
            print("Error: \(error.debugDescription)")
        }
    }
}
函数fileURLForBuggyWKWebView8是从@nacho4d复制的:

func fileURLForBuggyWKWebView8(fileURL: NSURL) throws -> NSURL {
    // Some safety checks
    var error:NSError? = nil;
    if (!fileURL.fileURL || !fileURL.checkResourceIsReachableAndReturnError(&error)) {
        throw error ?? NSError(
            domain: "BuggyWKWebViewDomain",
            code: 1001,
            userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("URL must be a file URL.", comment:"")])
    }

    // Create "/temp/www" directory
    let fm = NSFileManager.defaultManager()
    let tmpDirURL = NSURL.fileURLWithPath(NSTemporaryDirectory())
    try! fm.createDirectoryAtURL(tmpDirURL, withIntermediateDirectories: true, attributes: nil)

    // Now copy given file to the temp directory
    let dstURL = tmpDirURL.URLByAppendingPathComponent(fileURL.lastPathComponent!)
    let _ = try? fm.removeItemAtURL(dstURL)
    try! fm.copyItemAtURL(fileURL, toURL: dstURL)

    // Files in "/temp/www" load flawlesly :)
    return dstURL
}

如何在iOS 9上使用[WKWebView loadFileURL:allowingReadAccessToURL:]的示例

将web文件夹移动到项目时,请选择“创建文件夹引用”

然后使用如下代码(Swift 2):

在html文件中,使用如下文件路径

<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">

不是这样的

<link href="/bootstrap/css/bootstrap.min.css" rel="stylesheet">

移动到xcode项目的目录示例


< P>在试图在一个较大的HTML字符串中间显示局部图像的情况下,如:<代码> <代码>,它仍然没有出现在设备上,所以我将图像文件加载到NStATE中,并通过用数据本身替换SRC字符串来显示它。帮助构建要加载到WKWebView中的HTML字符串的示例代码,其中结果将替换src=“”引号中的内容:

Swift:

let pathURL = NSURL.fileURLWithPath(attachmentFilePath)
guard let path = pathURL.path else {
    return // throw error
}
guard let data = NSFileManager.defaultManager().contentsAtPath(path) else {
    return // throw error
}

let image = UIImage.init(data: data)
let base64String = data.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
result += "data:image/" + attachmentType + "base64," + base64String

var widthHeightString = "\""
if let image = image {
    widthHeightString += " width=\"\(image.size.width)\" height=\"\(image.size.height)\""
}

result += widthHeightString
NSURL *pathURL = [NSURL fileURLWithPath:attachmentFilePath];
NSString *path = [pathURL path];
NSData *data = [[NSFileManager defaultManager] contentsAtPath:path];

UIImage *image = [UIImage imageWithData:data];
NSString *base64String = [data base64EncodedStringWithOptions:0];
[result appendString:@"data:image/"];
[result appendString:attachmentType]; // jpg, gif etc.
[result appendString:@";base64,"];
[result appendString:base64String];

NSString *widthHeightString = @"\"";
if (image) {
    widthHeightString = [NSString stringWithFormat:@"\" width=\"%f\" height=\"%f\"", image.size.width, image.size.height];
}
[result appendString:widthHeightString];
目标-C:

let pathURL = NSURL.fileURLWithPath(attachmentFilePath)
guard let path = pathURL.path else {
    return // throw error
}
guard let data = NSFileManager.defaultManager().contentsAtPath(path) else {
    return // throw error
}

let image = UIImage.init(data: data)
let base64String = data.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
result += "data:image/" + attachmentType + "base64," + base64String

var widthHeightString = "\""
if let image = image {
    widthHeightString += " width=\"\(image.size.width)\" height=\"\(image.size.height)\""
}

result += widthHeightString
NSURL *pathURL = [NSURL fileURLWithPath:attachmentFilePath];
NSString *path = [pathURL path];
NSData *data = [[NSFileManager defaultManager] contentsAtPath:path];

UIImage *image = [UIImage imageWithData:data];
NSString *base64String = [data base64EncodedStringWithOptions:0];
[result appendString:@"data:image/"];
[result appendString:attachmentType]; // jpg, gif etc.
[result appendString:@";base64,"];
[result appendString:base64String];

NSString *widthHeightString = @"\"";
if (image) {
    widthHeightString = [NSString stringWithFormat:@"\" width=\"%f\" height=\"%f\"", image.size.width, image.size.height];
}
[result appendString:widthHeightString];

对于必须根据iOS8解决此问题的人员:

如果您的页面不复杂,您可以选择将该页面作为单个页面应用程序

换句话说,将所有资源嵌入html文件

要做: 1.将js/css文件的内容分别复制到html文件中的/tags中; 2.将图像文件转换为svg以相应地替换图像文件。 3.如前所述,使用[webView loadHTMLString:baseURL:]加载页面

这与设置svg图像的样式有点不同,但它不应该对您造成太多阻碍

页面呈现性能似乎降低了一点,但在iOS8/9/10下使用这样一个简单的解决方案是值得的

[configuration.preferences setValue:@"TRUE" forKey:@"allowFileAccessFromFileURLs"];
这为我解决了问题 iOS 8.0+

而且这似乎也很有效

NSString* FILE_PATH = [[[NSBundle mainBundle] resourcePath]
                       stringByAppendingPathComponent:@"htmlapp/FILE"];
[self.webView
    loadFileURL: [NSURL fileURLWithPath:FILE_PATH]
    allowingReadAccessToURL: [NSURL fileURLWithPath:FILE_PATH]
];

还可以尝试在viewDidLoad中将webView添加到视图层次结构中,并在ViewWillDisplay中加载请求。我的WKWebView仍在工作,但我就是这样拥有它的。如果请求不在视图层次结构中,WebView可能有一个不加载请求的优化?完成(viewDidLoad中的view.addView和ViewRequest中的loadRequest将出现),并且
NSString* FILE_PATH = [[[NSBundle mainBundle] resourcePath]
                       stringByAppendingPathComponent:@"htmlapp/FILE"];
[self.webView
    loadFileURL: [NSURL fileURLWithPath:FILE_PATH]
    allowingReadAccessToURL: [NSURL fileURLWithPath:FILE_PATH]
];