H5 与 APP 交互!

·  阅读 6802

目前,原生的 APP 主要分为 IOSAndroid 两大类。 IOS 没什么好说的,美国苹果公司独家打造的操作系统,用以抗衡 Google 公司出的 Android 操作系统。其他什么小米出的 MIUI 、锤子出的 Smartisan OS 等等一些都是基础 Android 改造的,也就是说底层还是 Android

当然,现在前端火起来了,随之而来的就是 H5APP 交互越来越频繁了,H5 要调用 APP 原生方法该怎么操作了,APP 要调起 H5 方法又该怎么操作呢?接下来,我们会一一讲解!

H5IOS 交互

申明:由于本人也不是做 IOS APP 开发的,所以只能是咨询这边 IOS APP 开发的同学,有错误的地方还希望大家指出。

由于这边的 IOS APP 开发用的是 ReactiveCocoa 。那 ReactiveCocoa 到底是什么呢?做 IOS APP 开发的同学应该不会陌生吧,它是由Github开源的一个应用于 IOSOS 开发的新框架, Cocoa 是苹果整套框架的简称,因此很多苹果框架喜欢以 Cocoa 结尾。具体的大家可以去研究研究。

接下来,重点来了!!

1、H5 调 APP

IOS APP
 /*! @abstract Adds a script message handler.
     @param scriptMessageHandler The message handler to add.
     @param name The name of the message handler.
     @discussion Adding a scriptMessageHandler adds a function
     window.webkit.messageHandlers.<name>.postMessage(<messageBody>) for all
     frames.
    */
    open func add(_ scriptMessageHandler: WKScriptMessageHandler, name: String)
复制代码

这段代码大致的意思是:添加一个消息脚本处理方法,传递的第一个参数是添加的消息处理方法,第二个参数是添加的消息处理的名称。

private (set) lazy var  webView: WKWebView = {
    //初始化一个 WKWebViewConfiguration
    let configuretion = WKWebViewConfiguration()
    configuretion.preferences = WKPreferences()
    configuretion.preferences.javaScriptEnabled = true
    configuretion.preferences.javaScriptCanOpenWindowsAutomatically = false
    
    //在 configuretion.userContentController 注册消息处理方法
    configuretion.userContentController = WKUserContentController()
    
    //注册uploadImage方法
    configuretion.userContentController.add(self, name: MessageHandlerName.uploadImage.rawValue)
    
    //注册login方法
    configuretion.userContentController.add(self, name: MessageHandlerName.login.rawValue)
    
     //注册home方法
    configuretion.userContentController.add(self, name: MessageHandlerName.home.rawValue)
    
    //初始化一个 WKWebView 并将配置参数传入
    let view = WKWebView.init(frame: .zero, configuration: configuretion)

    return view
}()
复制代码
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    let name = MessageHandlerName.init(rawValue: message.name)
    
    switch name {
    case .uploadImage?:
        //通过 message.body 获取 h5 传递的参数
        if let uploadType = message.body as? String {
            imageType = uploadType
        }
        
        // do your something
    case .login?:
        // do your something
    case .home?:
        // do your something
    default:
        break
    }
    
}
复制代码
H5
window.webkit.messageHandlers.zrbCallUpload.postMessage(this.type)
window.webkit.messageHandlers.login.postMessage(true)
window.webkit.messageHandlers.home.postMessage(true)
复制代码

window.webkit.messageHandlers APP 环境下注册的消息处理模块

zrbCallUpload APP 注册的具体的监听消息的方法

这里的调用是必选传参。

2、APP 调 H5

APP 调起 H5 方法最主要的一点是拼接回传的参数。

APP
let js = "callUploadHtml(\(JSONString!), \"\(self.imageType!)\")"
self.webView.evaluateJavaScript(js, completionHandler: { (_, _) in
                    
})
复制代码

注意:这里传递字符串时,必须要用引号引起来,否则会调用失败。

H5
    window.callUploadHtml = function(dataObj, uploadType){
        //do your something
    };
复制代码

注意:

  • 1、H5 定义 APP 调用的方法必须是在 window 全局下的,否则 APP 调用不到
  • 2、这里 H5 接受的参数必须和 APP 那边调用传递的参数一一对应。

具体的 demo 地址可以查看 https://github.com/littleLane/cross_ios_h5

H5 与 Android 交互

1、H5 调 APP

APP
    webView = (WebView) findViewById(R.id.web_H5Activity);
    progressBar = (ProgressBar) findViewById(R.id.progressBar_h5show);

    WebSettings settings = webView.getSettings();
    settings.setJavaScriptEnabled(true);
    webView.addJavascriptInterface(new JavaScriptObject(), "postMessage");
复制代码

APP 端设置的代码大致就是这样,获取 webView 然后设置 setJavaScriptEnabledtrue ,并添加 addJavascriptInterface 监听,设置全局的 JavaScript 方法处理 postMessage

接下来,定义一个 JavaScriptObject 类,并在该类里面添加你要处理 JavaScript 调用的方法,实例如下:

class JavaScriptObject {
    @JavascriptInterface//上传头像
    public void zrbCallUpload(String paramer, String returnFun) {
        //do your something
    }
    
    @JavascriptInterface//登录
    public void zrbLogin(Object paramer) { // TODO: 2018/1/11
        //do your something
    }
    
    ....
}
复制代码

到这里 APP 的事情已经做完了,下面就看前端怎么处理了!

H5
window.postMessage.zrbCallUpload(param1, param2);
window.postMessage.zrbLogin(param1);
复制代码

上面的两行代码就是 H5APP 的了,虽然看上去很简单,但是其中有几个需要注意的点:

  • 1、window 后面接的方法必须是 APP 定义好的监听方法,这里为 postMessage

  • 2、监听方法 postMessage 后面接的是具体逻辑调用的方法,这里分别是 zrbCallUploadzrbLogin

  • 3、这里的传参必须和 APP 那边确定好,和 APP 那边保持一致性,无论是参数的个数还是参数的类型。(最好这样,否者鬼知道会出什么问题)

APP 调 H5

H5

H5 这边事先要在全局 window 上定义好 APP 要回调的方法。

window.callUploadBack = function(params){
    // do your something
}
复制代码

这里的函数名要和 APP 调用的一致,其中传递的参数也要保持一致性,无论是参数的个数还是参数的类型。(最好这样,否者鬼知道会出什么问题)

APP
String js = "javascript:" + returnFun + "(" + params + ");";

webView.loadUrl(js);
复制代码
  • returnFun 调用的函数名称

  • params 回传的参数

这里一般是这样处理的,在 H5 调用 APP 方法时就把需要 APP 回调的方法传到 APP,如果不需要 APP 回调那就不需要传了。然后,APP 根据这个参数来拼接要回调 H5JavaScript 代码,形如上面的代码。