IOS中WKWebView 簡單使用
iOS開發之 WKWebVeiw使用
想用UIWebVeiw做的,但是突然想起來在iOS8中出了一個新的WKWebView,算是UIWebVeiw的升級版。本著對新事物的好奇,就上網查了一下,但是找了好多個都沒說的多了詳細,於是就問谷歌,找文件,看看使用方法,試用了一下,果然不錯,記錄下來,大家分享!
WKWebView的特點:
效能高,穩定性好,佔用的記憶體比較小,
支援JS互動
支援HTML5 新特性
可以新增進度條(然並卵,不好用,還是習慣第三方的)。
支援內建手勢,
據說高達60fps的重新整理頻率(不卡)
建立
- 匯入Wbkit這個類庫(WKWebVeiw包含在裡面的)
- 遵守協議(一般前兩個就行啦,第三個主要是與JS相關的東西,這個協議中包含一個必須實現的方法,這個方法是提高App與web端互動的關鍵,它可以直接將接收到的JS指令碼轉為OC或Swift物件--網上大神說的,我沒用過。)
@interface ViewController : UIViewController<WKNavigationDelegate,WKUIDelegate,WKScriptMessageHandler>
- 建立個WebView的物件
WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://www.baidu.com"]]];
[self.view addSubview:webView];
這裡有個注意點,網址一定要寫完整,加上https://
我剛開始懶,沒有加,屋裡怎麼試都載入不出來,顯示個白屏!!血的教訓啊!!
WKWebView有三個委託
WKWebView代理有兩個,是WKNavigationDelegate
和WKUIDelegate
,可以根據需要來決定用那些方法(當然使用之前不要忘了遵守協議)。
他們兩個的代理方法有好多個,不過有的不常用就不寫了,需要的自己點進去看一下就行啦。。。
1. WKNavigationDelegate
- WKNavigationDelegate來追蹤載入過程
// 頁面開始載入時呼叫
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation;
// 當內容開始返回時呼叫
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation;
// 頁面載入完成之後呼叫
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation;
// 頁面載入失敗時呼叫
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation;
- WKNavigtionDelegate來進行頁面跳轉
// 接收到伺服器跳轉請求之後再執行
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation;
// 在收到響應後,決定是否跳轉
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
// 在傳送請求之前,決定是否跳轉
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
2. WKUIDelegate
//1.建立一個新的WebVeiw
- (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures;
//2.WebVeiw關閉(9.0中的新方法)
- (void)webViewDidClose:(WKWebView *)webView NS_AVAILABLE(10_11, 9_0);
//3.顯示一個JS的Alert(與JS互動)
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler;
//4.彈出一個輸入框(與JS互動的)
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler;
//5.顯示一個確認框(JS的)
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler;
3.WKScriptMessageHandler
這個協議中包含一個必須實現的方法,這個方法是提高App與web端互動的關鍵,它可以直接將接收到的JS指令碼轉為OC或Swift物件。(當然,在UIWebView也可以通過“曲線救國”的方式與web進行互動,著名的Cordova框架就是這種機制)
// 從web介面中接收到一個指令碼時呼叫
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;
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) } }
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);}
WKWebView-JS執行方法
WKWebView JS執行方法與UIWebView不一樣了。
- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^)(id, NSError *))completionHandler;
completionHandler 擁有兩個引數,一個是返回錯誤,一個可以返回執行指令碼後的返回值
相關文章
- 簡單,使用WKWebViewWebView
- 簡單說說iOS之WKWebView的用法iOSWebView
- iOS中WKWebView互動使用總結iOSWebView
- iOS WKWebView的使用iOSWebView
- iOS WKWebView 基本使用iOSWebView
- iOS 中UIWebView與WKWebViewiOSUIWebView
- iOS - WKWebView CookieiOSWebViewCookie
- iOS MQTT 簡單使用流程iOSMQQT
- iOS WKWebView新增CookieiOSWebViewCookie
- iOS開發-WKWebView的介紹與基本使用iOSWebView
- iOS UIWebView、WKWebView注入CookieiOSUIWebViewCookie
- iOS--WKWebView Cookie注入iOSWebViewCookie
- iOS之WKWebView封裝iOSWebView封裝
- IOS 進階之 WKWebViewiOSWebView
- iOS 視訊播放的簡單使用iOS
- 【ios】ios 對於wkwebview白屏問題iOSWebView
- iOS-WKWebView 初步瞭解iOSWebView
- WKWebView 的使用WebView
- iOS逆向之四 FishHook的簡單使用iOSHook
- iOS 9 關鍵字的簡單使用iOS
- ios uiwebview wkwebview注意點小記iOSUIWebView
- iOS WKWebView新增進度條02iOSWebView
- 【iOS開發】從UIWebView到WKWebViewiOSUIWebView
- .Net Core中簡單使用MongoDBMongoDB
- React中useEffect的簡單使用React
- iOS UICollectionView的簡單使用和常用代理方法iOSUIView
- cacti+nagios之cacti的簡單使用(=)iOS
- ios 如何獲取WKWebview錯誤資訊iOSWebView
- [IOS]要多簡單有多簡單的IOS自動化calabash-iosiOS
- iOS FTPManager的簡單使用及常見問題iOSFTP
- js與ios橋接使用WebViewJavascriptBridge簡單理解JSiOS橋接WebViewJavaScript
- python中佇列簡單使用Python佇列
- Android中Lottie的簡單使用Android
- 【SQL Server中SMO的簡單使用】SQLServer
- SpringFramework中的AOP簡單使用SpringFramework
- ios11.2 使用wkwebview載入 html檔案行高失效iOSWebViewHTML
- WKWebview 的使用及坑WebView
- 使用WKWebView替換UIWebViewWebViewUI