国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

使用WKWebView替換UIWebView

2019-11-06 09:44:20
字體:
來源:轉載
供稿:網友

開發App的過程中,常常會遇到在App內部加載網頁,通常用UIWebView加載。這個自iOS2開始使用的網頁加載器一直是開發的心病:加載速度慢,占用內存多,優化困難。如果加載網頁多,還可能因為過量占用內存而給系統kill掉。各種優化的方法效果也不那么明顯(點擊查看常用優化方法)。

iOS8以后,蘋果推出了新框架Wekkit,提供了替換UIWebView組件WKWebView。各種UIWebView的問題沒有了,速度更快了,占用內存少了,一句話,WKWebView是App內部加載網頁的最佳選擇!

先看下 WKWebView的特性:

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

然后從以下幾個方面說下WKWebView的基本用法:

加載網頁加載的狀態回調新的WKUIDelegate協議動態加載并運行JS代碼webView 執行JS代碼JS調用App注冊過的方法

一、加載網頁

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

WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds];[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]]];[self.view addSubview:webView];

二、加載的狀態回調 (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;

頁面跳轉的代理方法:

// 接收到服務器跳轉請求之后調用- (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;

三、新的WKUIDelegate協議

這個協議主要用于WKWebView處理web界面的三種提示框(警告框、確認框、輸入框),下面是警告框的例子:

/** * web界面中有彈出警告框時調用 * * @param webView 實現該代理的webview * @param message 警告框中的內容 * @param frame 主窗口 * @param completionHandler 警告框消失調用 */- (void)webView:(WKWebView *)webView runJavascriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(void (^)())completionHandler;

四、動態加載并運行JS代碼

用于在客戶端內部加入JS代碼,并執行,示例如下:

// 圖片縮放的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 + '張圖');";// 根據JS字符串初始化WKUserScript對象WKUserScript *script = [[WKUserScript alloc] initWithSource:js injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];// 根據生成的WKUserScript對象,初始化WKWebViewConfigurationWKWebViewConfiguration *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];

五、webView 執行JS代碼

用戶調用用JS寫過的代碼,一般指服務端開發的:

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

六、JS調用App注冊過的方法

WKWebView里面注冊供JS調用的方法,是通過WKUserContentController類下面的方法:

- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;

scriptMessageHandler是代理回調,JS調用name方法后,OC會調用scriptMessageHandler指定的對象。

JS在調用OC注冊方法的時候要用下面的方式:

window.webkit.messageHandlers.<name>.postMessage(<messageBody>)

注意,name(方法名)是放在中間的,messageBody只能是一個對象,如果要傳多個值,需要封裝成數組,或者字典。整個示例如下:

//OC注冊供JS調用的方法[[_webView configuration].userContentController addScriptMessageHandler:self name:@"closeMe"];//OC在JS調用方法做的處理- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{ NSLog(@"JS 調用了 %@ 方法,傳回參數 %@",message.name,message.body);}//JS調用 window.webkit.messageHandlers.closeMe.postMessage(null);

如果你在selfdealloc打個斷點,會發現self沒有釋放!這顯然是不行的!谷歌后看到一種解決方法,如下:

@interface WeakScriptMessageDelegate : NSObject<WKScriptMessageHandler>@property (nonatomic, weak) id<WKScriptMessageHandler> scriptDelegate;- (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate;@end@implementation WeakScriptMessageDelegate- (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate{ self = [super init]; if (self) { _scriptDelegate = scriptDelegate; } return self;}- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{ [self.scriptDelegate userContentController:userContentController didReceiveScriptMessage:message];}@end

思路是另外創建一個代理對象,然后通過代理對象回調指定的self

WKUserContentController *userContentController = [[WKUserContentController alloc] init]; [userContentController addScriptMessageHandler:[[WeakScriptMessageDelegate alloc] initWithDelegate:self] name:@"closeMe"];

運行代碼,self釋放了,WeakScriptMessageDelegate卻沒有釋放啊啊啊!還需在selfdealloc里面 添加這樣一句代碼:

[[_webView configuration].userContentController removeScriptMessageHandlerForName:@"closeMe"];

OK,圓滿解決問題!

目前,大多數App需要支持iOS7以上的版本,而WKWebView只在iOS8后才能用,所以需要一個兼容性方案,既iOS7下用UIWebView,iOS8后用WKWebView。這個庫提供了這種兼容性方案:https://github.com/wangyangcc/IMYWebView

以上部分內容參考自:http://www.brighttj.com/ios/ios-wkwebview-new-features-and-use.html

在本人播客中地址:http://www.wangyangdev.com/2015/11/13/使用WKWebView替換UIWebView/


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 拉孜县| 尼勒克县| 永仁县| 临澧县| 衡阳市| 泰来县| 吉木萨尔县| 玛纳斯县| 新昌县| 冕宁县| 丹寨县| 旬邑县| 华池县| 托克逊县| 佛冈县| 罗山县| 沧州市| 英山县| 博爱县| 抚远县| 庄浪县| 宜章县| 河东区| 大足县| 鹤山市| 马关县| 昆明市| 台东县| 台江县| 台南县| 青海省| 包头市| 榆社县| 尚义县| 增城市| 南木林县| 拜泉县| 苏州市| 齐河县| 毕节市| 南涧|