| 簡介 |
iOS7之后蘋果推出了JavaScriptCore這個(gè)框架,從而讓web頁面和本地原生應(yīng)用交互起來非常方便,而且使用此框架可以做到Android那邊和iOS相對統(tǒng)一,web前端寫一套代碼就可以適配客戶端的兩個(gè)平臺,從而減少了web前端的工作量。 |
基于攔截協(xié)議進(jìn)行的封裝,學(xué)習(xí)成本相對JavaScriptCore較高,使用不如JavaScriptCore方便.關(guān)于JS交互,使用https://github.com/marcuswestin/WebViewJavascriptBridge支持UIWebView與WKWebView,并且在Android有一套對應(yīng)的https://github.com/lzyzsd/JsBridge,前端只需要寫一套。 |
iOS8之后出現(xiàn)的。功能更強(qiáng)大它與UIWebView相比較,擁有更快的加載速度和性能,更低的內(nèi)存占用。 |
| 交互 |
在ObjC中通過JSContext注入模型,然后調(diào)用模型的方法。(項(xiàng)目一般用該方式)第一步:需要聲明一個(gè)與JS進(jìn)行交互的協(xié)議(NativeApisProtocol),要求該協(xié)議遵守JSExport協(xié)議。第二步:新建一個(gè)模型(NativeAPIs),要求該模型遵守NativeApisProtocol協(xié)議。一般而言,需要在NativeAPIs模型中聲明一個(gè)JSContext屬性,便于與JS交互。第三步:實(shí)現(xiàn)該模型(NativeAPIs),即在NativeAPIs.m文件中實(shí)現(xiàn)NativeApisProtocol協(xié)議中定義的方法。第四步:在ViewController.m的-webViewDidFinishLoad:方法中獲取當(dāng)前JS執(zhí)行環(huán)境(self.jsContext),然后將NativeAPIs模型注入到JS執(zhí)行環(huán)境。 |
JS端如何使用· 第一步:將一段固定代碼放在JS中· 第二步:在固定的方法體里寫相關(guān)JS代碼,通過bridge.callHandler來調(diào)用iOS端 |
WKWebView和JavaScript交互1.導(dǎo)入WKUserContentController.h這個(gè)頭文件2.創(chuàng)建WKWebView的時(shí)候添加交互對象3.并讓交互對象實(shí)現(xiàn)WKScriptMessageHandler中的唯一的一個(gè)代理方法。 JavaScript調(diào)用Objective-C的時(shí)候,使用window.webkit.messageHandlers.funcName.postMessage(需要傳遞的參數(shù));而Objective-C在回調(diào)JavaScript的時(shí)候,要么執(zhí)行一段JavaScript代碼,或者就是調(diào)用JavaScript那邊的暴露的一個(gè)全局函數(shù)。一般是采用后者 |
| 缺點(diǎn) |
在-webViewDidFinishLoad:方法中注入NativeAPIs模型存在一定的問題,因?yàn)檫@時(shí)候網(wǎng)頁還沒加載完,JavaScript若開始調(diào)用Objective-C代碼(即NativeApisProtocol協(xié)議中定義的方法),會出現(xiàn)調(diào)用不到方法的問題。 解決方法:在每次創(chuàng)建JSContext環(huán)境的時(shí)候,都注入NativeAPIs模型到JSContext環(huán)境中。更加具體的方法可以參考第三方庫UIWebView-TS_JavaScriptContext。通過引入U(xiǎn)IWebView+TS_JavaScriptContext,讓ViewController遵守TSWebViewDelegate協(xié)議,實(shí)現(xiàn)代理協(xié)議中的方法-webView:didCreateJavaScriptContext:,以此獲取JSContext環(huán)境。 |
使用這個(gè)庫有什么缺點(diǎn)?最明顯的就是要固定加入相關(guān)代碼,而且JS代碼要放在固定的函數(shù)內(nèi)添加。那么安卓端是否也支持這樣呢?如果不支持,那么H5端要分別判斷ios、安卓?究竟是否通用。 |
WKWebView 使用的 WebKit 框架,交互時(shí)為 webkit.messageHandlers 注入對象,前端H5需要做判斷兩種不同注入方式帶來的不同調(diào)用方式· WKWebView的請求不能被NSURLProtocol截獲。· Cookie問題: WKWebView Cookie 問題在于 WKWebView 發(fā)起的請求不會自動帶上存儲于 NSHTTPCookieStorage 容器中的 Cookie 不允許跨域· 無法發(fā)送POST參數(shù)問題,dealloc后異步執(zhí)行js crash |
| 注意 |
注意:NativeApisProtocol協(xié)議中定義的方法是在子線程中執(zhí)行的,如果在所定義的方法中需要修改界面或者跳轉(zhuǎn)之類的,需要通過GCD回主線程操作。 |
|
1.VC銷毀時(shí),移除交互對象;如果不移除交互對象,則導(dǎo)致交互對象內(nèi)存常駐而引起內(nèi)存泄漏 [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"funcName"]; 2.WKWebView是在ios8.0之后推出的,但是清理緩存的功能是在ios9.0之后推出的。所以要判斷一下系統(tǒng)的版本,否則可能會導(dǎo)致程序崩潰 |