iOS WKWebView与JS交互及不能释放问题
2017-12-25 10:33
1676 查看
用户操作交互
就是截获JS调用alert、confirm、prompt函数,来使用原生控件实现样式及操作,并将用户操作回调给JS
代理:WKUIDelegate
具体步骤:
1、设置代理
2、完成代理方法
部分代理方法
演示:
自定义方法
就是截获JS调用自定义方法,实现某些功能
代理:WKScriptMessageHandler
具体步骤:
1、注册方法
2、实现WKScriptMessageHandler方法、注册的方法
3、移除监听
补充:
1、JS传递OC
2、OC传递JS
演示:
补充:JS文件
demo演示地址
⚠️ 坑:
1、WKWebView执行js代码,要先被加载到父视图上
2、关于不能释放问题的解决方案
思路:另外创建一个弱引用代理对象,然后通过代理对象回调指定的self
.h 文件
.m 文件
使用
1、导入该类
// addScriptMessageHandler 使用新类
2、依旧removeAllUserScripts
就是截获JS调用alert、confirm、prompt函数,来使用原生控件实现样式及操作,并将用户操作回调给JS
代理:WKUIDelegate
具体步骤:
1、设置代理
webView.UIDelegate = self;
2、完成代理方法
部分代理方法
// 在JS端调用alert函数时,会触发此代理方法。 // JS端调用alert时所传的数据可以通过message拿到 // 在原生得到结果后,需要回调JS,是通过completionHandler回调 -(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler; // JS端调用confirm函数时,会触发此方法 // 通过message可以拿到JS端所传的数据 // 在iOS端显示原生alert得到YES/NO后 // 通过completionHandler回调给JS端 -(void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler; // JS端调用prompt函数时,会触发此方法 // 要求输入一段文本 // 在原生输入得到文本内容后,通过completionHandler回调给JS - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler;
演示:
自定义方法
就是截获JS调用自定义方法,实现某些功能
代理:WKScriptMessageHandler
具体步骤:
1、注册方法
[webView.configuration.userContentController addScriptMessageHandler:self name:@"copyWeiXinHao"]; // 复制微信号 [webView.configuration.userContentController addScriptMessageHandler:self name:@"goToWeiXinApp"]; // 跳转微信App [webView.configuration.userContentController addScriptMessageHandler:self name:@"getCurrentContent"]; // 获取原生剪切板内容
2、实现WKScriptMessageHandler方法、注册的方法
// message.name为方法名 // message.body为js传递的参数,是个id类型 - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{ if ([message.name isEqualToString:@"copyWeiXinHao"]) { NSString *wxh = message.body; NSLog(@"微信号:%@",wxh); [self copyWeiXinHao:wxh]; } else if ([message.name isEqualToString:@"getCurrentContent"]) { NSString *content = [self getCurrentContent]; NSString *promptCode = [NSString stringWithFormat:@"getCurrentWeiXinHao(\"%@\")",content]; // OC传递数据给JS [self.webView.webView evaluateJavaScript:promptCode completionHandler:^(id _Nullable response, NSError * _Nullable error) { }]; } else if ([message.name isEqualToString:@"goToWeiXinApp"]) { [self goToWeiXinApp]; } } // 复制微信号 -(void)copyWeiXinHao:(NSString *)wxh{ [[UIPasteboard generalPasteboard] setString:wxh]; } // 当前剪切板信息 -(NSString*)getCurrentContent{ return [[UIPasteboard generalPasteboard] string]; } // 跳转微信应用 -(void)goToWeiXinApp{ NSURL *url = [NSURL URLWithString:@"weixin://"]; BOOL canOpen = [[UIApplication sharedApplication] canOpenURL:url]; if (canOpen){ //打开微信 [[UIApplication sharedApplication] openURL:url]; }else { NSLog(@"您的设备尚未安装微信"); } }
3、移除监听
-(void)dealloc{ // 根据name移除 [self.webView.webView.configuration.userContentController removeScriptMessageHandlerForName:@"copyWeiXinHao"]; // [self.webView.webView.configuration.userContentController removeAllUserScripts]; // 移除所有 }
补充:
1、JS传递OC
function 方法名() { window.webkit.messageHandlers.方法名.postMessage('参数'); }
2、OC传递JS
[webView evaluateJavaScript:@"方法名(参数)" completionHandler:^(id _Nullable response, NSError * _Nullable error) { }];
演示:
补充:JS文件
<!doctype html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, target-densitydpi=device-dpi"/> <title>JSCallOC</title> <style> * { //-webkit-tap-highlight-color: rgba(0,0,0,0); text-decoration: none; } html,body { -webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */ -webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */ -webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */ } #div-a { background:#FBA; color:#FFF; border-radius: 25px 5px; } </style> </head> <body style="background:#CDE; color:#FFF"> <div id="div-a"> <center> <br/> <input type="button" value=alert onclick="alert('禁止操作');" /> <br/> <br/> <input type="button" value="confirm" onclick="confirm('确定提交吗?');" /> <br/> <br/> <input type="button" value="prompt" onclick="prompt('请输入姓名');" /> <br/> <br/> <input type="button" value="复制微信号" onclick="copyWeiXinHao();" /> <br/> <br/> <input type="button" value="跳转微信" onclick="goToWeiXinApp();" /> <br/> <br/> <input type="button" value="获取应用剪切板内容" onclick="getCurrentContent();" /> <br/> <br/> <a id="push" href="#" onclick=""> xxx </a> </center> </div> <script type="text/javascript"> function copyWeiXinHao() { window.webkit.messageHandlers.copyWeiXinHao.postMessage('476512340'); } function goToWeiXinApp() { window.webkit.messageHandlers.goToWeiXinApp.postMessage(''); } function getCurrentContent() { window.webkit.messageHandlers.getCurrentContent.postMessage(''); } function getCurrentWeiXinHao(wxh) { document.getElementById('push').innerText = wxh; } </script> </body> </html>
demo演示地址
⚠️ 坑:
1、WKWebView执行js代码,要先被加载到父视图上
2、关于不能释放问题的解决方案
思路:另外创建一个弱引用代理对象,然后通过代理对象回调指定的self
.h 文件
#import <Foundation/Foundation.h> #import <WebKit/WebKit.h> @interface WeakScriptMessageDelegate : NSObject<WKScriptMessageHandler> @property (nonatomic,weak)id<WKScriptMessageHandler> scriptDelegate; - (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate; @end
.m 文件
#import "WeakScriptMessageDelegate.h" @implementation WeakScriptMessageDelegate - (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate { self = [super init]; if (self) { _scriptDelegate = scriptDelegate; } return self; } - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{ [self.scriptDelegate userContentController:userContentController didReceiveScriptMessage:message]; } @end
使用
1、导入该类
// addScriptMessageHandler 使用新类
[_webView.configuration.userContentController addScriptMessageHandler:[[WeakScriptMessageDelegate alloc] initWithDelegate:self] name:@"xxxx"];
2、依旧removeAllUserScripts
- (void)dealloc{ [self.webView.configuration.userContentController removeAllUserScripts]; }
相关文章推荐
- IOS UIWebView转WKWebView中的js交互问题
- IOS 使用 WKWebView 加载本地的JS和CSS文件出现乱码问题
- iOS用WKWebView与JS交互获取系统图片及WKWebView的Alert,Confirm,TextInput的监听代理方法使用,屏蔽WebView的可选菜单
- IOS中UIWebView、WKWebView之JS交互
- iOS(WKWebView)OC与JS交互 之三
- webview js 与java代码交互问题(成员变量名 和方法名不能重名 啃爹啊)
- iOS 加载HTML的相关问题(与JS的互相调用和WKWebView加载本地网页)
- iOS和JS交互教程之WKWebView-协议拦截详解
- WKWebView 基本使用及与JS交互,以及低版本系统崩溃问题解决
- IOS开发(7)WKWebView加载本地HTML、CSS、JS文件JS(解决html内访问其他资源路径问题)
- iOS 8 WkWebView 网页的配置和前进,后退,js 交互和进度条的加载
- iOS与js交互(WebView+WKWebView)
- iOS开发中的WKWebView与JS的交互
- ios WKWebView 与 JS 交互实战技巧
- WKWebView的基本使用,与网页h5交互,解决self不释放的问题
- [IOS开发]js与WKwebview交互Demo(调取二维码扫描)
- iOS-WKWebView特性以及与JS交互的一些事
- IOS 使用 WKWebView 加载本地的JS和CSS文件出现乱码问题
- iOS开发中OC与H5网页交互之OC传值给JS(WKWebView)
- iOS用WKWebView与JS交互获取系统图片及WKWebView的Alert,Confirm,TextInput的监听代理方法使用,屏蔽WebView的可选菜单