js与oc原⽣WKWebView交互传值
最近在做移动端实现H5⽀付,需要与JS交互,实现状态提醒,参数传值等,在这⾥总结⼀下,以防⼀个⽉后⼜忘了〜,
上⼀篇记录的apph5⽀付唤醒不了app,也是算⼀个bug有需要的可以去看⼀下
先看下四中交互⽅式:(我⽤的第三种,现在都是在⽤wkwebview不建议⽤webview)
1.拦截⽹址(适⽤于UIWebView和WKWebView)
2.JavaScriptCore(只适⽤于UIWebView,iOS7 +)
3.WKScriptMessageHandler(只适⽤于WKWebView,iOS8 +)
4.WebViewJavascriptBridge(适⽤于UIWebView和WKWebView,属于第三⽅框架)
1,2-不推荐
⽅法四WebViewJavascriptBridge
view ui框架是⼀个第三⽅框架,官⽅⽂档和demo都很完整,不再累赘,GitHub地址::
在这⾥主要记录⼀下⽅法三
@interface ViewController()<WKNavigationDelegate,UIScrollViewDelegate,WKUIDelegate,WKScriptMessageHandler> @property(⾮原⼦,强)WKWebView * webView;
@结束
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
WKWebViewConfiguration * config = [[WKWebViewConfiguration alloc] init];
config.preferences = [[WKPreferences alloc] init];
config.preferences.minimumFontSize = 10;
config.preferences.javaScriptEnabled = YES;
config.preferences.javaScriptCanOpenWindowsAutomatically = NO;
config.userContentController = [[WKUserContentController alloc] init];
config.processPool = [[WKProcessPool alloc] init];
self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds
configuration:config];
//记得实现对应协议,不然⽅法不会实现.
self.webView.UIDelegate = self;
self.webView.navigationDelegate =self;
[self.view addSubview:self.webView];
[self.webView loadRequest:[NSURLRequest requestWithURL:
[NSURL URLWithString:@"192.168.1.188/index1.html"]]];
// **************** 此处划重点 **************** //
/
/添加注⼊js⽅法, oc与js端对应实现
[config.userContentController addScriptMessageHandler:self name:@"collectSendKey"];
[config.userContentController addScriptMessageHandler:self name:@"collectIsLogin"];
}
#pragma mark - WKScriptMessageHandler
//实现JS注⼊⽅法的协议⽅法
- (void)userContentController:(WKUserContentController *)userContentController
didReceiveScriptMessage:(WKScriptMessage *)message {
//到对应的js端的⽅法名,获取messge.body
if([message.name isEqualToString:@“collectSendKey”]){
NSLog(@“%@”,message.body);
}
}
2.浏览⽹络页⾯,传递值给JS界⾯,JS界⾯通过值判断处理逻辑。
使⽤场景:浏览⽹页⾯商品,加⼊购物车,js通过oc原⽣传递过去的userId是否为空,来判断当前app是否登录,未登录,跳转原⽣界⾯登录,已登录,则直接加⼊购物车
直接放代码:
#pragma mark --------- WKNavigationDelegate --------------
//加载成功,传递值给js
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
{
//获取⽤户id
//传递userId给js端
NSString * userId = DEF_GET_OBJECT(UserID);
NSString * jsUserId;
if(!userId){
jsUserId = @“”;
}其他{
jsUserId = userId;
}
//之所以给userId重新赋值,貌似是如果userId为空null那么传给js端,js说⽆法判断,只好说,如果userId为null,重新定义为空字符串。如果⼤家有好的建议,可以在下⽅留⾔。
//同时,这个地⽅需要注意的是,JS端并不能查看我们给他传递的是什么值,也⽆法打印,貌似是语⾔问题?还是JS骗我⽂化低,反正,咱们把值传给他,根据双⽅商量好的逻辑,给出判断,如果正常,那就OK了。
NSString * jsStr = [NSString stringWithFormat:@“sendKey('%@')”,jsUserId];
[self.webView evaluateJavaScript:jsStr completionHandler:^(id _Nullable result,NSError * _Nullable error){
//此处可以打印错误。
}];
// JS端获取传递值代码实现实例(此处为JS端实现代码给⼤家粘出来⽰范的):
// function sendKey(user_id){
$( “#输⼊”)VAL(USER_ID)。
}
}
//依然是这个协议⽅法,获取注⼊⽅法名对象,获取JS返回的状态值。
#pragma mark - WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController
didReceiveScriptMessage:(WKScriptMessage *)message {
// js端判断如果userId为空,则返回字符串@“toLogin”,或者返回其它值。JS端代码实现实例(此处为JS端实现代码给⼤家粘出来⽰范的!):
function collectIsLogin(goods_id){
if(/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)){
尝试{
if($(“#input”)。val()){
llectGzhu.postMessage({body:“'”+ goods_id +“'”});
} else {
llectGzhu.postMessage({body:'toLogin'});
}
} catch(e){
//浏览器
alert(e);
}
// OC原⽣处理:
if([message.name isEqualToString:@“collectIsLogin”]){
NSDictionary * messageDict =(NSDictionary *)message.body;
if([messageDict [@“body”] isEqualToString:@“toLogin”]){
的NSLog(@ “登录”);
}其他{
的NSLog(@ “正常跳转”);
NSLog(@“mess --- id ==%@”,message.body);
}
}
}
3.在交互中,关于alert(单对话框)函数,确认(是/否对话框)函数,提⽰(输⼊型对话框)函数时,实现代理协议WKUIDelegate,则系统⽅法⾥有三个对应的协议⽅法。⼤家可以进⼊WKUIDelegate协议类⾯⾯查看。下⾯具体协议⽅法实现,也给⼤家粘出来,以供参考。
#pragma mark - WKUIDelegate
- (void)webViewDidClose:(WKWebView *)webView {
NSLog(@“%s”,__ FUNCTION__);
}
//在JS端调⽤alert函数时,会触发此代理⽅法。
// JS端调⽤alert时所传的数据可以通过消息拿到
//在原⽣得到结果后,需要回调JS,是通过completionHandler回调
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void(^)(void))completionHandler {
NSLog(@“%s”,__ FUNCTION__);
UIAlertController * alert = [UIAlertController alertControllerWithTitle:@“alert”消息:@“JS调⽤警报”preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@“确定”样式:UIAlertActionStyleDefault处理程序:^(UIAlertAction * _Nnnull action){
completionHandler();
}]];
[self presentViewController:alert animated:YES completion:NULL];
NSLog(@“%@”,消息);
}
// JS端调⽤确认函数时,会触发此⽅法
//通过消息可以拿到JS端所传的数据
//在iOS端显⽰原⽣警告得到是/否后
//通过completionHandler回调给JS端
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void(^)(BOOL result))completionHandler {
NSLog(@“%s”,__ FUNCTION__);
UIAlertController * alert = [UIAlertController alertControllerWithTitle:@“confirm”消息:@“JS调⽤确
认”preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@“确定”样式:UIAlertActionStyleDefault处理程序:^(UIAlertAction * _Nnnull action){
completionHandler(YES);
}]];
[alert addAction:[UIAlertAction actionWithTitle:@“取消”样式:UIAlertActionStyleCancel处理程序:^(UIAlertAction *
_Nnnull action){
completionHandler(NO);
}]];
[self presentViewController:alert animated:YES completion:NULL];
NSLog(@“%@”,消息);
}
// JS端调⽤提⽰函数时,会触发此⽅法
//要求输⼊⼀段⽂本
//在原⽣输⼊得到⽂本内容后,通过completionHandler回调给JS
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText :( nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void(^)(NSString * __nullable result))completionHandler {
NSLog(@“%s”,__ FUNCTION__);
NSLog(@“%@”,提⽰);
UIAlertController * alert = [UIAlertController alertControllerWithTitle:@“textinput”message:@“JS调⽤输⼊
框”preferredStyle:UIAlertControllerStyleAlert];
[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField){
}];
[alert addAction:[UIAlertAction actionWithTitle:@“确定”样式:UIAlertActionStyleDefault处理程序:^(UIAlertAction *
_Nnnull action){
completionHandler([[Fields lastObject] text]);
}]];
[self presentViewController:alert animated:YES completion:NULL];
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论