Skip to content

Latest commit

 

History

History
128 lines (88 loc) · 4.03 KB

033. js 与原生通信.md

File metadata and controls

128 lines (88 loc) · 4.03 KB

一、概述

现在原生混合H5开发已经司空见惯了,那么在开发过程中必然会涉及到原生与H5之间的通信,本篇文章主要给大家安利下H5如何与原生进行通信的。

二、交互

1. Query

此交互方式主要用于原生将数据通过 query 的形式传递给H5,如:

http://www.xxx.com/share?code=xxx&q=ma

在H5这边需要截取处理解析参数,通常不建议通过 query 传递敏感数据。

2. Cookie

原生在使用 Webview 加载 H5 时,可以注入 Cookie,H5 直接从 Cookie 中读取数据即可,比如 token 等信息。

3. Scheme

Scheme 是一种页面内跳转协议,通过定义自己的Scheme协议,可以非常方便的跳转APP中的各个页面。

为了方便使用,我们封装了一个 js 库,点击前往 >>

4. 预埋方法

在实际开发中,产品可能经常会加一些需求,特别是对于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);
        }
    }
}

三、扩展

1. 与iOS 通信

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);
    }
}

2. 与Android通信

Android 调用 JS

在window定义方法,将方法名给安卓那边调用即可。同iOS调用JS。

JS 调用 Android

安卓映射方法名调用/安卓那边绑定方法至window,js直接调用方法即可。可以观察上述示例,我们这边调用安卓的形式:

window.js_android.setClipboard(text);

四、收尾

好了,各位小伙伴,本篇文章就到这里啦,希望能帮到大家,如果有不正之处,请留言。