• WKWebView使用遇到的坑--加载本地html及JS交互


    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 拥有两个参数,一个是返回错误,一个可以返回执行脚本后的返回值

  • 相关阅读:
    2018.7.12训练赛 -K
    winter 2018 02 01 关于模运算的一道题
    debug(实验)
    problem-1003(恢复一下)
    hd acm1466
    hd acm2045
    hd acm 1297
    hd acm1005
    hd acm1425
    概率趣题:三个犯人
  • 原文地址:https://www.cnblogs.com/duzhaoquan/p/6016757.html
Copyright © 2020-2023  润新知