WKWebView使用遇到的坑--加载本地html

1. ios9以前版本读取本地HTML的问题

当使用loadRequest来读取本地的HTML时,WKWebView是无法读取成功的,后台会出现如下的提示:
Could not create a sandbox extension for /
原因是WKWebView是不允许通过loadRequest的方法来加载本地根目录的HTML文件
而在iOS9的SDK中加入了以下方法来加载本地的HTML文件:
[WKWebView loadFileURL:allowingReadAccessToURL:]
但是在iOS9以下的版本是没提供这个便利的方法的。以下为解决方案的思路,就是在iOS9以下版本时,先将本地HTML文件的数据copy到tmp目录中,然后再使用loadRequest来加载。但是如果在HTML中加入了其他资源文件,例如js,css,image等必须一同copy到temp中。这个是最蛋疼的事情了。

解决方法如下

1.Objective-C:

//将文件copy到tmp目录
- (NSURL *)fileURLForBuggyWKWebView8:(NSURL *)fileURL {
    NSError *error = nil;
    if (!fileURL.fileURL || ![fileURL checkResourceIsReachableAndReturnError:&error]) {
        return nil;
    }
    // Create "/temp/www" directory
    NSFileManager *fileManager= [NSFileManager defaultManager];
    NSURL *temDirURL = [[NSURL fileURLWithPath:NSTemporaryDirectory()] URLByAppendingPathComponent:@"www"];
    [fileManager createDirectoryAtURL:temDirURL withIntermediateDirectories:YES attributes:nil error:&error];

    NSURL *dstURL = [temDirURL URLByAppendingPathComponent:fileURL.lastPathComponent];
    // Now copy given file to the temp directory
    [fileManager removeItemAtURL:dstURL error:&error];
    [fileManager copyItemAtURL:fileURL toURL:dstURL error:&error];
    // Files in "/temp/www" load flawlesly :)
    return dstURL;
}

//调用逻辑
 NSString *path = [[NSBundle mainBundle] pathForResource:@"indexoff" ofType:@"html"];
    if(path){
        if ([[UIDevice currentDevice].systemVersion floatValue] >= 9.0) {
            // iOS9. One year later things are OK.
            NSURL *fileURL = [NSURL fileURLWithPath:path];
            [self.webView loadFileURL:fileURL allowingReadAccessToURL:fileURL];
        } else {
            // iOS8. Things can be workaround-ed
            //   Brave people can do just this
            //   fileURL = try! pathForBuggyWKWebView8(fileURL)
            //   webView.loadRequest(NSURLRequest(URL: fileURL))

            NSURL *fileURL = [self.fileHelper fileURLForBuggyWKWebView8:[NSURL fileURLWithPath:path]];
            NSURLRequest *request = [NSURLRequest requestWithURL:fileURL];
            [self.webView loadRequest:request];
        }
    }

2.Swift

//将文件copy到tmp目录
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()).URLByAppendingPathComponent("www")
    try! fm.createDirectoryAtURL(tmpDirURL, withIntermediateDirectories: true, attributes: nil)

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

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

//方法调用

    var filePath = NSBundle.mainBundle().pathForResource("file", ofType: "pdf")

    if #available(iOS 9.0, *) {
        // iOS9. One year later things are OK.
        webView.loadFileURL(fileURL, allowingReadAccessToURL: fileURL)
    } else {
        // iOS8. Things can be workaround-ed
        //   Brave people can do just this
        //   fileURL = try! pathForBuggyWKWebView8(fileURL)
        //   webView.loadRequest(NSURLRequest(URL: fileURL))
        do {
            fileURL = try fileURLForBuggyWKWebView8(fileURL)
            webView.loadRequest(NSURLRequest(URL: fileURL))
        } catch let error as NSError {
            print("Error: " + error.debugDescription)
        }
    }

2. WKWebView - WKNavigationDelegate使用

特别提醒一点,在使用以下delegate的方法时

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler

需执行decisionHandler的block。

例如:

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {

    NSURLRequest *request = navigationAction.request;
    WMPageActionType actionType = ActionTypeNone;
    WKNavigationActionPolicy actionPolicy = WKNavigationActionPolicyAllow;
    if([request.URL.absoluteString hasPrefix:OC_CLOSE_REQUEST]){
        actionType = ActionTypeClose;
        actionPolicy = WKNavigationActionPolicyCancel;
    }
    if(self.actionDelegate && [self.actionDelegate respondsToSelector:@selector(webView:action:type:)]) {
        [self.actionDelegate webView:webView action:navigationAction type:actionType];
    }
   //这句是必须加上的,不然会异常
    decisionHandler(actionPolicy);
}

3.WKWebView-JS执行方法

WKWebView JS执行方法与UIWebView不一样了。

- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^)(id, NSError *))completionHandler;

completionHandler 拥有两个参数,一个是返回错误,一个可以返回执行脚本后的返回值

时间: 2024-10-13 08:21:38

WKWebView使用遇到的坑--加载本地html的相关文章

微信小程序-工具无法加载本地模拟开发服务的解决办法

微信小程序开发工具出现如下问题: 因为网络代理软件或者 VPN 影响,工具无法加载本地模拟开发服务  请尝试以下任一解决方案1.关闭相关网络代理软件,重新编译成功后,再启动相关网络代理软件: 2.配置相关软件不针对 *.appservice.open.weixin.qq.com 和 *.debug.open.weixin.qq.com 进行代理: 3.配置相关软件不针对 开发者工具 做代理 但是根本没用任何代理,找了很多方法,最终解决: 设置windows防火墙,允许微信web开发者工具使用网络

解决maven无法加载本地lib/下的jar包问题(程序包XXX不存在)

这次一个项目用到maven编译,我在本地开发的时候jar包都是放在WEB-INF/lib目录下,通过 BuildPath将jar包导入,然后用MyEclipse中的:maven package命令打成war包,这个war包在tomcat下能正常运行,war包下是有lib下的jar包的. 但是我往服务器上传的是项目源码,用SVN上传,然后服务器上用maven插件编译运行,编译时报错:找不到WEB-INF/lib下jar包.显然maven编译时不会自动加载WEB-INF/lib下的jar包. 项目的

as3.0加载本地或网络上的图片

加载本地或网络上的图片,我们一般只用Loader及URLRequest这两个类就可以完成,URLRequest即可以加载本地的,也可以加载网络的.代码如下 import flash.display.Loader; import flash.net.URLRequest; var loader:Loader = new Loader(); var request:URLRequest = new URLRequest('img/123.png'); loader.y = 200; loader.l

World Wind Java开发之八——加载本地缓存文件构建大范围三维场景

上一篇博客主要是针对小文件直接导入WW中显示,然而当文件特别大时,这种方式就不太可行.因此要将大文件切片,生成本地缓存,WW可以加载本地缓存文件,保障浏览场景时的流畅性. 1.使用Global Mapper生成WW缓存切片 使用Global Mapper生成WW缓存切片的步骤已上传至使用GlobalMapper生成WW缓存切片,这里不再赘述.生成后的切片可以放在任意文件夹下,目前参考了WWJ自带的例子InstallImageryAndElevationsDemo,暂时将数据放在C:\Progra

[Android学习系列2]用webview写界面,加载本地js,js,html文件

以jquery mobile为例 1.在android界面拖入一个webview,然后添加一个internet权限 <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <uses-permission android:name="android.permission.INTERNET"/> <application ........

iOS WebView 加载本地资源(图片,文件等)

NSString *path = [[NSBundle mainBundle] pathForResource:@"关于.docx" ofType:nil]; NSURL *url = [NSURL fileURLWithPath:path]; NSLog(@"%@", [self mimeType:url]); //webview加载本地文件,可以使用加载数据的方式 //第一个诶参数是一个NSData, 本地文件对应的数据 //第二个参数是MIMEType //第

iOS开发-UIWebView加载本地和网络数据

UIWebView是内置的浏览器控件,可以用它来浏览网页.打开文档,关于浏览网页榜样可以参考UC,手机必备浏览器,至于文档浏览的手机很多图书阅读软件,UIWebView是一个混合体,具体的功能控件内置的,实现一些基本的功能.UIWebView可以查看Html网页,pdf文件,docx文件,txt文件文件,系统自带的Safari就是UIWebView实现的. 基础布局 页面布局很简单就是一个文本框,一个按钮,一个UIWebView,页面布局如下: 如果想简单一点的话,其实用UIWebView也行,

ios网络学习------4 UIWebView的加载本地数据的三种方式

UIWebView是IOS内置的浏览器,可以浏览网页,打开文档  html/htm  pdf   docx  txt等格式的文件.  safari浏览器就是通过UIWebView做的. 服务器将MIME的标识符等放入传送的数据中告诉浏览器使用那种插件读取相关文件. uiwebview加载各种本地文件(通过loadData方法): - (void)viewDidLoad { [super viewDidLoad]; [self setupUI]; NSString *path = [[NSBund

UIWebView加载本地HTML文件

写本文的原因是今天被要求「调研在iOS中加载本地HTML的相关技术」,好记性不如烂笔头,将一些东西给记录下来吧. 应用场景是这样的:手头的iOS App有一部分UI需要使用HTML完成,好处是这部分UI可以更灵活,即可以在任何不需要升级App的情况下更新这部分UI(包括样式.操作等等).当下非常火的技术 – Facebook的React Native – 正是用来解决这种问题的,毕竟在传统的开发模式下,更新UI必须要升级App,而升级App是一个非常耗时的过程.使用Web App部分代替Nati