WebView
項(xiàng)目中功能多了,就會(huì)加載一些H5界面谣膳。這個(gè)時(shí)候就會(huì)用到WebView紊浩。再?gòu)?fù)雜一點(diǎn)就會(huì)用到原生與H5交互。舉個(gè)例子琅豆,項(xiàng)目中經(jīng)常會(huì)有一些活動(dòng)界面。然而這些活動(dòng)界面總是在變化篓吁。用原生代碼寫(xiě)茫因,維護(hù)成本較高。這個(gè)時(shí)候就可以用H5代替杖剪。這就會(huì)用到H5與原生相互調(diào)用节腐。
關(guān)于WebView的創(chuàng)建,H5加載頁(yè)面摘盆。我就不貼出來(lái)代碼了。直接說(shuō)一下 JavaScriptCore框架饱苟。這是蘋(píng)果解決與H5交互專用框架孩擂。框架中有幾個(gè)類需要注意:
JSContext.h(聯(lián)系H5與原生的橋梁功能與CoreData中的context類似)箱熬;
JSValue.h(用于獲取H5中的任意對(duì)象)类垦;
JSExport.h(一個(gè)協(xié)議調(diào)用的時(shí)候會(huì)用到)狈邑;
最后要知道,所有的調(diào)用方法基本上都是在- (void)webViewDidFinishLoad:(UIWebView *)webView里面完成蚤认。也就是頁(yè)面加載完成時(shí)候調(diào)用米苹。
JSContext創(chuàng)建:
self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];//創(chuàng)建
self.context.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue)
{
context.exception = exceptionValue;
};檢測(cè)是否創(chuàng)建成功
H5調(diào)用原生
使用block
H5代碼:
<button onclick="myAction();" style="">點(diǎn)擊按鈕返回上一個(gè)頁(yè)面</button>
//如需傳值,在方法名后面的括號(hào)里面加上即可
原生代碼:
self.context[@"myAction"] = ^(){
};//在小括號(hào)中接收H5傳過(guò)來(lái)的參數(shù)砰琢,需要保持類型一致蘸嘶,在大括號(hào)中實(shí)現(xiàn)調(diào)用原生的方法;
使用JSExport代理
<button onclick="native.myLog();">調(diào)用OC中myLog方法</button>
//在括號(hào)中添加需要傳遞的參數(shù)
原生代碼:
創(chuàng)建代理陪汽,當(dāng)前控制器遵循代理即WebExport
@protocol WebExport <JSExport>
JSExportAs
(myLog ,- (void)myOCLog :(NSString *)string);
指定代理(在- (void)webViewDidFinishLoad:(UIWebView *)webView方法中)
self.context[@"native"] = self;
實(shí)現(xiàn)代理方法
- (void)myOCLog :(NSString *)string{
NSLog(@"%@");
}
以上就是JS調(diào)用原生的基本使用训唱。
原生調(diào)用H5
H5代碼
<b id="label">需要改變的標(biāo)簽</b>
原生代碼(在你需要觸發(fā)的地方添加)
JSValue *labelAction = self.context[@"labelAction"];//使用JSValue接收f(shuō)angaf
[labelAction callWithArguments:@[@"你好"]];
參考文檔
http://www.reibang.com/p/0428d0734379
WKWebView
相對(duì)來(lái)說(shuō)WKWebView交互起來(lái)就比較麻煩啦,感覺(jué)沒(méi)有WebView順手挚冤。同樣關(guān)于WKWebView的創(chuàng)建我就不貼出代碼了
H5調(diào)用原生
原生代碼(在- (void)viewDidLoad 方法中)
//配置環(huán)境
self.configuration = [[WKWebViewConfiguration alloc]init];
self.userVC = [[WKUserContentController alloc]init];
//注冊(cè)方法
[self.userVC addScriptMessageHandler:self name:@"sayhello"];
self.configuration.userContentController = self.userVC;
接收參數(shù)
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
NSLog(@"%@",message.body);//body中就是接收的參數(shù)
}
H5代碼
<html>
<body>
<h1>hello world</h1>
<button onclick="say()">say hello</button>
</body>
<script>
function say(){
//前端需要用 window.webkit.messageHandlers.注冊(cè)的方法名.postMessage({body:傳輸?shù)臄?shù)據(jù)} 來(lái)給native發(fā)送消息
window.webkit.messageHandlers.sayhello.postMessage({body: 'hello world!'});
//這句很重要况增,利用WKWebView的新特性MessageHandler來(lái)實(shí)現(xiàn)JS調(diào)用原生方法,很多博客都沒(méi)有寫(xiě)上這句训挡,所以導(dǎo)致我一直沒(méi)有成功
}
</script>
</html>
參考文檔
http://www.reibang.com/p/4fa8c4eb1316
http://blog.sina.com.cn/s/blog_83b89df10102xuce.html