WebView
項目中功能多了萍虽,就會加載一些H5界面。這個時候就會用到WebView膜楷。再復雜一點就會用到原生與H5交互旭咽。舉個例子,項目中經(jīng)常會有一些活動界面赌厅。然而這些活動界面總是在變化穷绵。用原生代碼寫,維護成本較高特愿。這個時候就可以用H5代替仲墨。這就會用到H5與原生相互調(diào)用勾缭。
關(guān)于WebView的創(chuàng)建,H5加載頁面目养。我就不貼出來代碼了漫拭。直接說一下 JavaScriptCore框架。這是蘋果解決與H5交互專用框架混稽〔勺ぃ框架中有幾個類需要注意:
JSContext.h(聯(lián)系H5與原生的橋梁功能與CoreData中的context類似);
JSValue.h(用于獲取H5中的任意對象)匈勋;
JSExport.h(一個協(xié)議調(diào)用的時候會用到)礼旅;
最后要知道,所有的調(diào)用方法基本上都是在- (void)webViewDidFinishLoad:(UIWebView *)webView里面完成洽洁。也就是頁面加載完成時候調(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;
};檢測是否創(chuàng)建成功
H5調(diào)用原生
使用block
H5代碼:
<button onclick="myAction();" style="">點擊按鈕返回上一個頁面</button>
//如需傳值,在方法名后面的括號里面加上即可
原生代碼:
self.context[@"myAction"] = ^(){
};
//在小括號中接收H5傳過來的參數(shù)饿自,需要保持類型一致汰翠,在大括號中實現(xiàn)調(diào)用原生的方法;
使用JSExport代理
<button onclick="native.myLog();">調(diào)用OC中myLog方法</button>
//在小括號中添加需要傳遞的參數(shù)
原生代碼:
創(chuàng)建代理昭雌,當前控制器遵循代理即WebExport
@protocol WebExport <JSExport>
JSExportAs
(myLog ,- (void)myOCLog :(NSString *)string);
指定代理(在- (void)webViewDidFinishLoad:(UIWebView *)webView方法中)
self.context[@"native"] = self;
實現(xiàn)代理方法
- (void)myOCLog :(NSString *)string{
NSLog(@"%@");
}
以上就是JS調(diào)用原生的基本使用复唤。
原生調(diào)用H5
H5代碼
<b id="label">需要改變的標簽</b>
原生代碼(在你需要觸發(fā)的地方添加)
JSValue *labelAction = self.context[@"labelAction"];//使用JSValue接收fangaf
[labelAction callWithArguments:@[@"你好"]];
參考文檔
(http://www.reibang.com/p/0428d0734379)
WKWebView
相對來說WKWebView交互起來就比較麻煩啦,感覺沒有WebView順手烛卧。同樣關(guān)于WKWebView的創(chuàng)建我就不貼出代碼了
H5調(diào)用原生
原生代碼(在- (void)viewDidLoad 方法中)
//配置環(huán)境
self.configuration = [[WKWebViewConfiguration alloc]init];
self.userVC = [[WKUserContentController alloc]init];
//注冊方法
[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>
<head>
<script>
function say()
{
//前端需要用 window.webkit.messageHandlers.注冊的方法名.postMessage({body:傳輸?shù)臄?shù)據(jù)} 來給native發(fā)送消息
window.webkit.messageHandlers.sayhello.postMessage({body: 'hello world!'});
//這句很重要佛纫,利用WKWebView的新特性MessageHandler來實現(xiàn)JS調(diào)用原生方法,很多博客都沒有寫上這句总放,所以導致我一直沒有成功
}
</script>
</head>
<body>
<h1>hello world</h1>
<button onclick="say()">say hello</button>
</body>
</html>
原生調(diào)用H5
原生代碼
- (void)webView:(WKWebView *)tmpWebView didFinishNavigation:(WKNavigation *)navigation{
//say()是JS方法名呈宇,completionHandler是異步回調(diào)block
[webView evaluateJavaScript:@"say()" completionHandler:^(id _Nullable result, NSError * _Nullable error) {
NSLog(@"%@",result);
}];
}