移动端iOS混合开发WebViewJavascriptBridge使用总结
镇长前言
本文记录webView和JS交互的基本使用,也算是对WebViewJavascriptBridge初步认识。
版本:5.0
地址:Github
原生端
原生端配置
初始化
创建WebViewJavascriptBridge对象
1 2
| _bridge = [WebViewJavascriptBridge bridgeForWebView:_webViewjs]; [_bridge setWebViewDelegate:self];
|
初始化方法:bridgeForWebView实现如下
1 2 3 4 5 6 7 8 9 10 11 12
| + (instancetype)bridgeForWebView:(WVJB_WEBVIEW_TYPE*)webView { WebViewJavascriptBridge* bridge = [[self alloc] init]; [bridge _platformSpecificSetup:webView]; return bridge; } //调用如下方法 - (void) _platformSpecificSetup:(WVJB_WEBVIEW_TYPE*)webView { _webView = webView; _webView.delegate = self; _base = [[WebViewJavascriptBridgeBase alloc] init]; _base.delegate = self; }
|
内部初始化了一个WebViewJavascriptBridgeBase对象,并对_webView和_base赋值。
注册一个方法,用来响应JS调用
1 2 3 4 5 6
| - (void)registShareFunction { [_bridge registerHandler:@"ShareClick" handler:^(id data, WVJBResponseCallback responseCallback) { NSLog(@"-----分享数据:%@", data); //实现需要的操作 }]; }
|
参数:ShareClick
是handler的名字,与网页中JS调用的handler名字相同(写错了就慢慢找吧,别问我是怎么知道的)。data
是JS发送过来的数据。responseCallback
回调数据给JS。
注册一个方法,用来调用JS
1 2 3
| [_bridge callHandler:@"OCtoJS" data:@"一个字符串" responseCallback:^(id responseData) { NSLog(@"%@", responseData); }];
|
参数说明:OCtoJS
是handler名字。data
发送给JS的数据。responseCallback
响应JS的回调。
下面是ViewController完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| #import "ViewController.h" #import <WebViewJavascriptBridge.h> #import "SecondViewController.h" @interface ViewController ()<UIWebViewDelegate> @property (weak, nonatomic) IBOutlet UIWebView *webViewjs; @property (nonatomic, strong) WebViewJavascriptBridge *bridge; @end @implementation ViewController
- (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(right)]; [WebViewJavascriptBridge enableLogging]; _bridge = [WebViewJavascriptBridge bridgeForWebView:_webViewjs]; [_bridge setWebViewDelegate:self]; [self loadExamplePage:_webViewjs]; [self registShareFunction]; } - (void)right{ [_bridge callHandler:@"OCtoJS" data:@"一个字符串" responseCallback:^(id responseData) { NSLog(@"%@", responseData); }]; } - (void)loadExamplePage:(UIWebView*)webView { NSString* htmlPath = [[NSBundle mainBundle] pathForResource:@"jsDemo" ofType:@"html"]; NSString* appHtml = [NSString stringWithContentsOfFile:htmlPath encoding:NSUTF8StringEncoding error:nil]; NSURL *baseURL = [NSURL fileURLWithPath:htmlPath]; [webView loadHTMLString:appHtml baseURL:baseURL]; } - (void)registShareFunction { [_bridge registerHandler:@"ShareClick" handler:^(id data, WVJBResponseCallback responseCallback) { NSLog(@"-----分享数据:%@", data); //实现需要的操作 SecondViewController *secondVC = [[SecondViewController alloc] init]; UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:secondVC]; [self presentViewController:nav animated:YES completion:^{ responseCallback(@"分享成功"); }]; }]; } @end
|
index.html页面分析
配置index.html
WebViewJavascriptBridge是通过拦截URL来实现调用原生功能。下面是html中必须配置的JS方法。
1 2 3 4 5 6 7 8 9 10 11
| function setupWebViewJavascriptBridge(callback) { if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); } if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); } window.WVJBCallbacks = [callback]; var WVJBIframe = document.createElement('iframe'); WVJBIframe.style.display = 'none'; WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__'; document.documentElement.appendChild(WVJBIframe); setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0) }
|
具体如何实现的这里不多分析,请自行Google。
注册方法,用来OC响应调用。
1 2 3 4 5 6
| setupWebViewJavascriptBridge(function(bridge) { bridge.registerHandler('OCtoJS', function(data, responseCallback) { alert('JS方法被调用' + data); responseCallback('JS执行过了'); }) })
|
只有在setupWebViewJavascriptBridge
中注册的方法才能被OC调用。可以在其中定义多个方法用来响应OC。注意OCtoJS
和前面handler名称是对应的。
JS调用OC方法
1 2 3 4 5 6
| function ShareClick(){ var item = '我是JS发送来的数据'; WebViewJavascriptBridge.callHandler('ShareClick',item, function(response){ alert('response'); }) }
|
index.html完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0"> <title>测试</title> </head> <body> <script type="text/javascript"> //监听程序 function setupWebViewJavascriptBridge(callback) { if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); } if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); } window.WVJBCallbacks = [callback]; var WVJBIframe = document.createElement('iframe'); WVJBIframe.style.display = 'none'; WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__'; document.documentElement.appendChild(WVJBIframe); setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0) } setupWebViewJavascriptBridge(function(bridge) { bridge.registerHandler('OCtoJS', function(data, responseCallback) { alert('JS方法被调用' + data); responseCallback('JS执行过了'); }) }) function ShareClick(){ var item = '我是JS发送来的数据'; WebViewJavascriptBridge.callHandler('ShareClick',item, function(response){
}) } </script> <button id="button" onclick="ShareClick()">点击调用支付宝</button> </body> </html>
|