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中。這個是最蛋疼的事情了。css

解決方法以下

1.Objective-C:html

//將文件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.Swiftjava

//將文件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的方法時ios

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

需執行decisionHandler的block。web

例如:dom

- (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執行方法ide

WKWebView JS執行方法與UIWebView不同了。ui

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

completionHandler 擁有兩個參數,一個是返回錯誤,一個能夠返回執行腳本後的返回值this

相關文章
相關標籤/搜索