最近,我使用WKWebView和React.js进行双向通信,自己写了React.js嵌入到Native中。
Native操作Web,通过两种方式传值
第一种,通过JS传值给Native
通过这种方式,可以通过Swift执行DOM操作,顺便说一句,webView.evaluateJavaScript返回脚本执行结果的内容。这个处理程序似乎是在主线程上执行的。
Native调用JS代码方法如下:
let str = "payResult(true)" webView.evaluateJavaScript(str) { (result, error) in }
Javascript处理逻辑方法如下:
payResult = value => { if (value === true ) { console .log('true' ) this .setState(prevState => ({ pushnotice: '1' })); } else { console .log('false' ) this .setState(prevState => ({ pushnotice: '0' })); } }
如果JS的payResult方法没有调用,那就加上这样一句话window.payResult,有可能被组件屏蔽无法全局调用。
constructor (props) { super (props); window .payResult = this .payResult }
第二种,通过get请求传值
通过get请求方式将参数传到js的请求URL链接中。
var url = "" if let webUrl = webUrl { url = webUrl if let uid = userID { url += "?" + "uid=" + uid } if let topicId = topicId { url += "&" + "topic=" + topicId } if isRank == true { url += "&" + "type=2" } }
react.js通过URL拼接方式解析传递的参数,方法如下:
var params = {}let str = this .props.location.searchlet seg = str.replace(/^?/ , '' ).split('&' )let len = seg.lengthfor (var i = 0 ; i < len; i++) { if (seg[i]) { let p = seg[i].split('=' ); params[p[0 ]] = p[1 ]; } }
通过这种方式params.uid | param.topic | param.type 来获取参数
Native操作Web,通过两种方式传值
Native操作
实例化WKWebViewConfiguration和WKUserContentController,userController在JavaScript的注册处理调用名称。并设置实现WKScriptMessageHandler协议的代理。
let webConfiguration = WKWebViewConfiguration ()webConfiguration.preferences = WKPreferences () webConfiguration.preferences.minimumFontSize = 10 ; webConfiguration.p 大专栏 React.js/HTML5和iOS双向通信 references.javaScriptEnabled = true ; webConfiguration.preferences.javaScriptCanOpenWindowsAutomatically = false ; webConfiguration.userContentController = WKUserContentController () webConfiguration.processPool = WKProcessPool () webConfiguration.userContentController.add(self as WKScriptMessageHandler , name:"pushAction" ) let webView = WKWebView (frame: .zero, configuration: webConfiguration)webView.scrollView.bounces = false webView.scrollView.showsVerticalScrollIndicator = false webView.scrollView.showsHorizontalScrollIndicator = false
通过WKScriptMessageHandler协议进行监控
func (_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { print (message.name) print (message.body) jsInvokeNativeHandler(message) } func jsInvokeNativeHandler (_ message: WKScriptMessage) { if message.isKind(of: WKScriptMessage .self ) { let serialQueue = DispatchQueue (label: "com.test.mySerialQueue" ) serialQueue.sync { if message.name == "pushAction" { if let dict : NSDictionary = message.body as ? NSDictionary { if let content = dict["content" ] as ? String { self .sendPushNotification(content) } } } } }
关于解析,和Web进行协议,我在H5写的代码通过message传过来的是一个字典类型 {content: ‘…’}。
web端操作
H5如何传递方法给native?
传值方法如下,iOS和Android接受的方法不同,要单独进行处理:
window .htmlCallMobileDeja = function (handlerMethod, parameters ) { try { var u = navigator.userAgent; var isAndroid = u.indexOf('Android' ) > -1 || u.indexOf('Adr' ) > -1 var isiOS = !!u.match(/(i[^;]+;( U;)? CPU.+Mac OS X/ ) if (isiOS) { if (window .webkit) { window .webkit.messageHandlers[handlerMethod].postMessage(dic); console .log(handlerMethod) } } else if (isAndroid){ window ['JsClient' ][handlerMethod](parameters) } else { } } catch (err) { console .log('The native context does not exist yet' ); } };
javascript通过这种方式进行传值
var dic = { 'event_name' : event_name + '' , 'event_first_param' : event_first_param + '' , 'event_second_param' : event_second_param + '' , } window .htmlCallMobileDeja('hideMBP' , dic)
React.js/HTML5和iOS双向通信