现在原生混合H5开发已经司空见惯了,那么在开发过程中必然会涉及到原生与H5之间的通信,本篇文章主要给大家安利下H5如何与原生进行通信的。
此交互方式主要用于原生将数据通过 query
的形式传递给H5,如:
http://www.xxx.com/share?code=xxx&q=ma
在H5这边需要截取处理解析参数,通常不建议通过 query
传递敏感数据。
原生在使用 Webview
加载 H5 时,可以注入 Cookie,H5 直接从 Cookie 中读取数据即可,比如 token
等信息。
Scheme 是一种页面内跳转协议,通过定义自己的Scheme协议,可以非常方便的跳转APP中的各个页面。
为了方便使用,我们封装了一个 js 库,点击前往 >>
在实际开发中,产品可能经常会加一些需求,特别是对于H5端,经常会发布,无奈有的需求必须要原生才能实现,比如分享海报到微信,如果原生已经发包那就不好处理了,因为不可能为了这一个功能原生再发包吧,原生经常发包体验是不友好的,所以为了避免类似情况出现,我也组织我们大前端部门一起讨论,针对未来可能会出现的一些需求进行埋点,先把一些交互的方法封装进去,这里我列举一些我们项目中用到的。
首先是原生那边要定义的方法,如下:
openBrowser(url: string): void;
同样的,为了方便我在H5中使用,我也是做了如下封装:
/**
* 跳转至外部浏览器
* @param {string} url 跳转地址
*/
export function openBrowser(url) {
if (Validator.ios()) {
try {
window.webkit.messageHandlers.openBrowser.postMessage(url);
} catch (err) {
console.log(err);
}
} else if (Validator.android()) {
try {
window.js_android.openBrowser(url);
} catch (err) {
console.log(err);
}
}
}
iOS 调用 JS
在window定义方法,将方法名给iOS那边调用即可。很多同学不知道如何在类似于vue、react中定义,这里给大家举一个示例:
window['refresh'] = () => {
Toast.info('原生调用refresh')
}
提示:如果你要在某个组件中使用,可以将上述代码定义在生命周期中。
JS 调用 iOS
// 1. 直接调用
window.webkit.messageHandlers.<方法名>.postMessage(<数据>)
// 2. 同步返回/发送数据给iOS,并同步获取iOS返回的数据
// 思路:js 通过 prompt 发送,将需要传送的数据以JSON对象形式作为prompt参数
prompt(JSON.stringify({key:value, ...}))
// 「iOS:拦截prompt」
// 设置代理
self.webView.UIDelegate = self;
// JS端调用prompt函数时,会触发此代理方法。
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler {
NSError *err = nil;
NSData *dataFromString = [prompt dataUsingEncoding:NSUTF8StringEncoding];
// 读取数据
NSDictionary *data = [NSJSONSerialization JSONObjectWithData:dataFromString options:NSJSONReadingMutableContainers error:&err];
if (!err){
// 返回数据
completionHandler(returnValue);
}
}
Android 调用 JS
在window定义方法,将方法名给安卓那边调用即可。同iOS调用JS。
JS 调用 Android
安卓映射方法名调用/安卓那边绑定方法至window,js直接调用方法即可。可以观察上述示例,我们这边调用安卓的形式:
window.js_android.setClipboard(text);
好了,各位小伙伴,本篇文章就到这里啦,希望能帮到大家,如果有不正之处,请留言。