使用WKWebView替換UIWebView

轉(zhuǎn)載地址:http://www.reibang.com/p/4fa8c4eb1316

開發(fā)App的過程中腿宰,常常會遇到在App內(nèi)部加載網(wǎng)頁,通常用UIWebView加載吃度。這個自iOS2開始使用的網(wǎng)頁加載器一直是開發(fā)的心病:加載速度慢伊者,占用內(nèi)存多间护,優(yōu)化困難。如果加載網(wǎng)頁多兑牡,還可能因為過量占用內(nèi)存而給系統(tǒng)kill掉。各種優(yōu)化的方法效果也不那么明顯(點擊查看常用優(yōu)化方法)亿虽。

iOS8以后苞也,蘋果推出了新框架Wekkit,提供了替換UIWebView的組件WKWebView如迟。各種UIWebView的問題沒有了殷勘,速度更快了此再,占用內(nèi)存少了玲销,一句話,WKWebView是App內(nèi)部加載網(wǎng)頁的最佳選擇策吠!

先看下WKWebView的特性:

在性能瘩绒、穩(wěn)定性、功能方面有很大提升(最直觀的體現(xiàn)就是加載網(wǎng)頁是占用的內(nèi)存蟀给,模擬器加載百度與開源中國網(wǎng)站時,WKWebView占用23M坤溃,而UIWebView占用85M);

允許JavaScript的Nitro庫加載并使用(UIWebView中限制);

支持了更多的HTML5特性越驻;

高達60fps的滾動刷新率以及內(nèi)置手勢;

將UIWebViewDelegate與UIWebView重構(gòu)成了14類與3個協(xié)議(查看蘋果官方文檔)记劈;

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

加載網(wǎng)頁

加載的狀態(tài)回調(diào)

新的WKUIDelegate協(xié)議

動態(tài)加載并運行JS代碼

webView 執(zhí)行JS代碼

JS調(diào)用App注冊過的方法

一并巍、加載網(wǎng)頁

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

WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds];[webView loadRequest:[NSURLRequestrequestWithURL:[NSURLURLWithString:@"http://www.baidu.com"]]];[self.viewaddSubview:webView];

二刽射、加載的狀態(tài)回調(diào) (WKNavigationDelegate)

用來追蹤加載過程(頁面開始加載剃执、加載完成、加載失斏龅怠)的方法:

// 頁面開始加載時調(diào)用- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation;// 當(dāng)內(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;

頁面跳轉(zhuǎn)的代理方法:

// 接收到服務(wù)器跳轉(zhuǎn)請求之后調(diào)用- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation;// 在收到響應(yīng)后怒见,決定是否跳轉(zhuǎn)- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void(^)(WKNavigationResponsePolicy))decisionHandler;// 在發(fā)送請求之前,決定是否跳轉(zhuǎn)- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler;

三闺阱、新的WKUIDelegate協(xié)議

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

/** *? web界面中有彈出警告框時調(diào)用 * *@paramwebView? ? ? ? ? 實現(xiàn)該代理的webview *@parammessage? ? ? ? ? 警告框中的內(nèi)容 *@paramframe? ? ? ? ? ? 主窗口 *@paramcompletionHandler 警告框消失調(diào)用 */- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(void(^)())completionHandler;

四、動態(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對象黔姜,初始化WKWebViewConfigurationWKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];[config.userContentControlleraddUserScript:script];_webView = [[WKWebView alloc] initWithFrame:self.view.boundsconfiguration:config];[_webView loadHTMLString:@""baseURL:nil];[self.viewaddSubview:_webView];

五蒂萎、webView 執(zhí)行JS代碼

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

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

六泻拦、JS調(diào)用App注冊過的方法

再WKWebView里面注冊供JS調(diào)用的方法,是通過WKUserContentController類下面的方法:

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

scriptMessageHandler是代理回調(diào)争拐,JS調(diào)用name方法后,OC會調(diào)用scriptMessageHandler指定的對象隘冲。

JS在調(diào)用OC注冊方法的時候要用下面的方式:

window.webkit.messageHandlers..postMessage()

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

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

如果你在self的dealloc打個斷點画舌,會發(fā)現(xiàn)self沒有釋放已慢!這顯然是不行的!谷歌后看到一種解決方法佑惠,如下:

@interfaceWeakScriptMessageDelegate:NSObject@property(nonatomic,weak)id scriptDelegate;- (instancetype)initWithDelegate:(id)scriptDelegate;@end@implementationWeakScriptMessageDelegate- (instancetype)initWithDelegate:(id)scriptDelegate{self= [superinit];if(self) {? ? ? ? _scriptDelegate = scriptDelegate;? ? }returnself;}- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{? ? [self.scriptDelegateuserContentController:userContentController didReceiveScriptMessage:message];}@end

思路是另外創(chuàng)建一個代理對象,然后通過代理對象回調(diào)指定的self旭咽,

WKUserContentController*userContentController = [[WKUserContentControlleralloc]init];? ? [userContentController addScriptMessageHandler:[[WeakScriptMessageDelegatealloc] initWithDelegate:self] name:@"closeMe"];

運行代碼,self釋放了轿塔,WeakScriptMessageDelegate卻沒有釋放啊啊扒攵狻!

還需在self的dealloc里面 添加這樣一句代碼:

[[_webView configuration].userContentControllerremoveScriptMessageHandlerForName:@"closeMe"];

OK宗收,圓滿解決問題亚兄!

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

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

文/wangyangyang(簡書作者)

原文鏈接:http://www.reibang.com/p/6ba2507445e4

著作權(quán)歸作者所有昭雌,轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)健田,并標(biāo)注“簡書作者”。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末总放,一起剝皮案震驚了整個濱河市好爬,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌哎榴,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件迎变,死亡現(xiàn)場離奇詭異飘言,居然都是意外死亡衣形,警方通過查閱死者的電腦和手機姿鸿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門苛预,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人热某,你說我怎么就攤上這事〕锿拢” “怎么了秘遏?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長洋侨。 經(jīng)常有香客問我铡俐,道長,這世上最難降的妖魔是什么审丘? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任滩报,我火速辦了婚禮,結(jié)果婚禮上脓钾,老公的妹妹穿的比我還像新娘。我一直安慰自己昌妹,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布烂叔。 她就那樣靜靜地躺著固歪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪牢裳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天忘朝,我揣著相機與錄音判帮,去河邊找鬼。 笑死脊另,一個胖子當(dāng)著我的面吹牛约巷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播踩麦,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼氓癌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了反粥?” 一聲冷哼從身側(cè)響起疲迂,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎郑气,沒想到半個月后腰池,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體忙芒,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡讳侨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了甘桑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片歹叮。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖德谅,靈堂內(nèi)的尸體忽然破棺而出萨螺,到底是詐尸還是另有隱情,我是刑警寧澤慰技,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站掏颊,受9級特大地震影響艾帐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜柒爸,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一捎稚、第九天 我趴在偏房一處隱蔽的房頂上張望乐横。 院中可真熱鬧阳藻,春花似錦、人聲如沸匾南。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽豹爹。三九已至,卻和暖如春臂聋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背孩等。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工肄方, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人权她。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓隅要,卻偏偏與公主長得像蝴罪,于是被迫代替她去往敵國和親步清。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,864評論 2 354

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

  • 開發(fā)App的過程中询微,常常會遇到在App內(nèi)部加載網(wǎng)頁崖瞭,通常用UIWebView加載撑毛。這個自iOS2開始使用的網(wǎng)頁加載...
    皮皮瑞閱讀 364評論 0 0
  • 原文地址:http://www.reibang.com/p/6ba2507445e4 開發(fā)App的過程中藻雌,常常會遇...
    默默_David閱讀 679評論 0 0
  • 在iOS開發(fā)APP的過程中,我們都是用webview來完成一些網(wǎng)頁HTML胯杭、JS的加載,webview加載速度慢鸽心,...
    LuxDark閱讀 2,107評論 7 38
  • 開發(fā)App的過程中,常常會遇到在App內(nèi)部加載網(wǎng)頁藤肢,通常用UIWebView加載。這個自iOS2開始使用的網(wǎng)頁加載...
    ch32053閱讀 147,171評論 145 706
  • 本篇文章系轉(zhuǎn)載嘁圈,僅用來學(xué)習(xí)蟀淮,作者 wangyangyang,文中的作者鏈接也一并保存原文地址:http://www...
    張不二01閱讀 3,519評論 0 8