iOS WKWebView用法及與js交互

<p>

APP開發(fā)過程中,內(nèi)部加載網(wǎng)頁是很常見的交互,手機端經(jīng)常使用webView加載網(wǎng)頁相關頁面。iOS8之前通常使用UIWebView,但是UIWebView的通病一直得不到有效的解決,比如:加載速度慢,占用內(nèi)存多,優(yōu)化困難,加載網(wǎng)頁過多的話還有可能因為占用內(nèi)存過大而被系統(tǒng)kill掉等。

蘋果為了解決這個問題,在iOS8之后推出了替換UIWebView的新組件WKWebView,基本上各種問題都得到了解決,現(xiàn)在WKWebView 是APP內(nèi)部加載網(wǎng)頁的最佳選擇。

其新特性:
1.在性能、穩(wěn)定性、功能方面有很大提升(最直觀的體現(xiàn)就是加載網(wǎng)頁是占用的內(nèi)存,模擬器加載百度與開源中國網(wǎng)站時,WKWebView占用23M,而UIWebView占用85M);
2.允許JavaScript的Nitro庫加載并使用(UIWebView中限制);
3.支持了更多的HTML5特性;
4.高達60fps的滾動刷新率以及內(nèi)置手勢;
5.將UIWebViewDelegate與UIWebView重構成了14類與3個協(xié)議(查看蘋果官方文檔

基本用法:
1.加載網(wǎng)頁
2.加載的狀態(tài)回調(diào)
3.新的WKUIDelegate協(xié)議
4.動態(tài)加載并運行JS代碼
5.webView 執(zhí)行JS代碼
6.JS調(diào)用App注冊過的方法

用法概述:

1.加載網(wǎng)頁:

加載網(wǎng)頁或HTML代碼的方式與UIWebView相同,代碼示例如下:

WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];
[self.view addSubview:webView];
2.加載的狀態(tài)回調(diào)即代理(WKNavigationDelegate)方法實現(xiàn)

用來追蹤加載過程(頁面開始加載、加載完成、加載失敗)的方法:

// 頁面開始加載時調(diào)用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation;
// 當內(nèi)容開始返回時調(diào)用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation;
// 頁面加載完成之后調(diào)用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation;
// 頁面加載失敗時調(diào)用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation;

頁面跳轉的代理方法:

// 接收到服務器跳轉請求之后調(diào)用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation;
// 在收到響應后,決定是否跳轉
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
// 在發(fā)送請求之前,決定是否跳轉
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler;
3.新的WKUIDelegate協(xié)議

與JS的alert、confirm、prompt交互,我們希望用自己的原生界面,而不是JS的,就可以使用這個代理類來實現(xiàn)。

  1. alert警告框函數(shù):
//alert 警告框
-(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
  UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"警告" message:@"調(diào)用alert提示框" preferredStyle:UIAlertControllerStyleAlert];
  [alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
      completionHandler();
  }]];
  [self presentViewController:alert animated:YES completion:nil];
  NSLog(@"alert message:%@",message);
}
  1. confirm確認框函數(shù):
//confirm 確認框
-(void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"確認框" message:@"調(diào)用confirm提示框" preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(YES);
    }]];
    [alert addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(NO);
    }]];
    [self presentViewController:alert animated:YES completion:NULL];
}
  1. prompt 輸入框函數(shù):
//confirm 確認框
-(void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"輸入框" message:@"調(diào)用輸入框" preferredStyle:UIAlertControllerStyleAlert];
    [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        textField.textColor = [UIColor blackColor];
    }];
    
    [alert addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler([[alert.textFields lastObject] text]);
    }]];
    
    [self presentViewController:alert animated:YES completion:NULL];
}
4.動態(tài)加載并運行JS代碼

用于在客戶端內(nèi)部加入JS代碼,并執(zhí)行,示例如下:

// 圖片縮放的js代碼
NSString *js = @"var count = document.images.length;for (var i = 0; i < count; i++) {var image = document.images[i];image.style.width=320;};window.alert('找到' + count + '張圖');";
// 根據(jù)JS字符串初始化WKUserScript對象
WKUserScript *script = [[WKUserScript alloc] initWithSource:js injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
// 根據(jù)生成的WKUserScript對象,初始化WKWebViewConfiguration
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
[config.userContentController addUserScript:script];
_webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config];
[_webView loadHTMLString:@"<head></head><imgea src='http://www.nsu.edu.cn/v/2014v3/img/background/3.jpg' />"baseURL:nil];
[self.view addSubview:_webView];
5. webView 執(zhí)行JS代碼:

用戶調(diào)用用JS寫過的代碼,一般指服務端開發(fā)的:

//javaScriptString是JS方法名,completionHandler是異步回調(diào)block
[self.webView evaluateJavaScript:javaScriptString completionHandler:completionHandler];

最后Demo地址:

WKWebViewdemo

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容