写在前面

很久没更新了,真的是没时间,周末要做兼职,工作日要加班赶项目,筋疲力尽了,今天稍微好点,更新一下吧,最近用的一些东西!

问题描述

我们开发一款软件,其中涉及到一些支付的问题,这边担心IOS的App无法通过AppleStore的审核,所以中间支付的模块使用H5进行内嵌,也就是直接使用webview进行调起H5完成对应的功能,

代码

/**
 * @FUNCTION memberRecharge
 * @params NaviType是否需要显示导航栏 1 不显示 2 显示 3 会员充值(比较特殊的一个) 4 白色有背景(禁掉系统的导航栏,使用自己的导航栏)
 * @params NaviIntro 导航栏显示的文字
 * @params NaviColor 导航栏的颜色
 * @params ArchiveColor 文案的颜色
 * @desc   本地调试的时候可以关闭当前代码的调用 因为本地的时候是没有该方法的,浏览器会直接报错!
 */
function NaviInfo(arg) {
	console.log(arg)
	try {
		window.ios.memberRecharge(arg);
	} catch (error) {
		try{
			window.webkit.messageHandlers.memberRecharge.postMessage(arg);
		}catch(e){
			console.log("can not find Function of IOS" + e)
		}
	}
}
export default NaviInfo

PS:简单的解释一下,memberRecharge是IOS定义的方法名,H5调用的时候我这里为什么写了两个呢?同一个方法,使用两种不同的方式进行调用,原因是IOS8版本之前他们是不支持最新的写法的,所以为了兼容IOS8版本之前的手机,要写两种调用的方法,这里是一个公共的方法,我们直接进行系统方法进行判断是安卓还是IOS,直接调这个方法就可以了,具体参数怎么定义,这个不一定,看H5和IOS怎么约定的!上面的这个全局方案是为了解决我们自定义头部的问题,当然用法是一样的!

配置为全局方法

import Vue from 'vue'
import App from './App'
import http from './static/js/request.js'
import naviinfo from './static/js/commonNavi.js'


Vue.config.productionTip = false
App.mpType = 'app'

Vue.prototype.$http = http
Vue.prototype.$naviinfo = naviinfo  //全局的交互方法

const app = new Vue({
    ...App
})
app.$mount()

页面调用

/**
			 * @FUNCTION memberRecharge
			 * @params NaviType是否需要显示导航栏 1 不显示 2 显示 3 会员充值(比较特殊的一个) 4 白色有背景(禁掉系统的导航栏,使用自己的导航栏)
			 * @params NaviIntro 导航栏显示的文字
			 * @params NaviColor 导航栏的颜色
			 * @params ArchiveColor 文案的颜色
			 */
			let params_obj = {
				NaviType: "3",
				NaviIntro: "会员充值",
				NaviColor: "",
				ArchiveColor: ""
			}
			this.$naviinfo(JSON.stringify(params_obj))

判断当前终端

if (this.ish5) {
					history.go(-1);
				} else if (this.ua.indexOf('Android') > -1 || this.ua.indexOf('Adr') > -1) { // 安卓
					jsInAndroid.goback()
					// window.android.submitData('goback',null);
				} else if (this.ua.match(/MicroMessenger/i) == 'micromessenger') { // 微信
					console.log("微信环境下")
					//}else {
				} else if (!!this.ua.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)) { // IOS
					window.webkit.messageHandlers.goback.postMessage({
						func: 'goback',
						shareLink: null
					});
				}

PS:第一个ish5 是一个死的值,我是通过options也就是页面的url上面获取的,这个是我们约定好的,h5的时候是直接调用系统的返回就可以了,否则就直接调用对应终端的返回

ios如何调用h5的方法

以上的都是H5进行调用ios和安卓的一些问题,他们使用H5内嵌的时候,总会有一些事需要他们调用我们的方法的时候,这个时候是有一些坑的,比如我们使用了框架进行开发的页面,ios和安卓调用js方法的前提是你的方法是挂载在window上的,如果没有挂载,就调不起来,所以下面以react框架为例,说一下怎么讲我们方法挂载到window上!

react 将函数挂载到window

constructor(props) {
    super(props);
    this.topicShare = this.topicShare.bind(this);
  }
componentWillUpdate() {
    //将函数挂载到windows上进行IOS和安卓交互
    window.topicShare = this.topicShare;
  } 
 /**
   * @function  topicShare 话题分享功能
   */
topicShare() {
    const { topicDetail, isAndroid } = this.state;
    try {
      if (isAndroid) {
        window.jsInAndroid.topicShare(topicDetail.TopicId);
      } else {
        window.ios.topicShare(topicDetail.TopicId);
      }
    } catch (error) {
      console.log(error);
    }
  }

PS:我们需要将自己的函数挂载到构造器上,然后在页面加载或者更新的或者更新结束的地方进行挂载window就可以!

vue 将函数挂载到window

mounted() {
     window['funcDemo'] = () => {
        this.goDemo()
     }
}
methods: {
    goDemo() {
      //nothing
    }
 }

PS: 如何验证是不是已经挂载到window上,直接将页面打开调试模式,进行window控制台打印,有该函数就是挂载成功了!

总结

个人建议还是独立端完成的就直接独立完成,不要使用内嵌的,虽然没什么问题,但是数据交互的还是比较恶心的!先写到这里吧!