web与Android和iOS的webview数据交互,兼容写法

数据交互实现参照(本方案以vue为例介绍):

https://blog.csdn.net/qq_44393166/article/details/105097286

https://blog.csdn.net/lyyo_cd/article/details/84304864

https://www.jianshu.com/p/f63bab6c90e0

首先通过以下方法确认登录设备为Android还是iOS,如果是iOS可进一步判断是否为iPad
(由于有些iPad内核显示使用了macOS系统,所以这里用触点区分,如有更好的方案可替代)

  // iPad可能装载Mac OS 
 export function isIPad() {
  var userAgentInfo = navigator.userAgent
  var Agents = ['iPad','Mac']
  var flag = false
  var v = 0
  for (; v < Agents.length; v++) {
    if (userAgentInfo.indexOf(Agents[v]) > 0) {
      // iPad触点为5  Mac为0
      if (navigator.maxTouchPoints==0) {
        flag = "Mac"
      }else{
        flag = "iPad"
      }
      break
    }
  }
  return flag
}
export function mobileInfo() {
  var u = navigator.userAgent
  if (u.indexOf('Android') > -1 || u.indexOf('Linux') > -1) {
    //安卓手机
    return '安卓'
  } else if (u.indexOf('iPhone') > -1) {
    //苹果手机
    return '苹果'
  } else if (u.indexOf('Windows Phone') > -1) {
    //winphone手机
    return 'winphone'
  }
}

随后可通过以下方法完成与安卓、ios的数据互通。

// 访问ios、安卓
const sysInfo = mobileInfo()
const isIPadInfo = isIPad() == 'iPad'
// 调用原生方法(无回调)
export function setFn(methods, params) {
  if (params == null) {
    if (sysInfo == '安卓') {
      window.android[methods]()
    }
    if (sysInfo == '苹果' || isIPadInfo) {
      window.webkit.messageHandlers[methods].postMessage('')
    }
  } else {
    let data = params
    if (typeof data !== 'string') data = JSON.stringify(data)
    if (sysInfo == '安卓') {
      window.android[methods](data)
    }
    if (sysInfo == '苹果' || isIPadInfo) {
      window.webkit.messageHandlers[methods].postMessage(data)
    }
  }
}

// 调用原生方法(有回调)
export function set(methods, params, fn) {
  let fName = methods + 'Jg'
  get([{ [fName]: fn }])
  if (params == null) {
    if (sysInfo == '安卓') {
      window.android[methods]()
    }
    if (sysInfo == '苹果' || isIPadInfo) {
      window.webkit.messageHandlers[methods].postMessage()
    }
  } else {
    let data = params
    if (typeof data !== 'string') data = JSON.stringify(data)
    if (sysInfo == '安卓') {
      window.android[methods](data, fName)
    }
    if (sysInfo == '苹果' || isIPadInfo) {
      window.webkit.messageHandlers[methods].postMessage(data, fName)
    }
  }
}
// 提供方法给原生调用
export function get(fnArr) {
  fnArr.forEach(el => {
    for (var key in el) {
      window[key] = el[key]
    }
  })
}
  • get的作用是web暴露给 android 与 ios 自己的方法
  • set与setFn的作用是web去使用 android 与 ios 提供的方法

因没有找到web访问移动端原生后回调函数写法、这里就模拟了回调函数的方式,即:
采用原生提供的方法名+Jg的方式给原生层定义web提供的方法,并让原生层执行,以达到回调函数的目的。
使用原生方法时,就调用原生方法后边的js逻辑不执行的问题,可采用 上述回调函数 的方式激活方法。

原生调用vue中方法:
  methods: {
    // 测试方法
    ceshi() {
      console.log("测试方法1")
    },
    // 测试方法
    ceshi2() {
      console.log("测试方法2")
    },
  },
  mounted() {
  //暴露方法给安卓、ios
   get( [{ ceshi: this.ceshi, ceshi2: this.ceshi2 }])
  }
vue中调用原生方法:
  methods: {
    // 测试方法
    ceshi1() {
      const _this = this//需要转this
      set('callAndroid', { test: '测试' }, function(res) {
        alert('接收到的' + res)
      })
    },
    // 测试方法
    ceshi2() {
      setFn('callAndroid', { test: '测试' })
    }
  }

第一个参数为原生提供给web的方法名。
第二个参数为传递的参数,不传参时写null。
第三个参数为原生调用的该方法的回调函数。
(setFn没有第三个参数、只有set有)

Android调用web方法:
bridgeJavascript(){
	let that = this;
	window.WebViewJavascriptBridge.callHandler(
		'ceshi1'//与web一起定义的共同方法名
		,{} // 参数
		,function(res){//web方法返回值
		 	res=JSON.parse(res);
		 	alert(res)
		 }
	)
}
Android提供方法给web调用:
window.WebViewJavascriptBridge.send(	//提供方法名为send的方法给web调用
	data		//需要传递的消息参数
	,function(res){		//返回的响应
		alert(res)
	}
)
iOS调用web方法:
// 调用JS方法
        webView.evaluateJavaScript("ceshi1" + "('\(token)')") { (result, err) in
            // result是JS返回的值
            print(result as? String ?? "" , err.description)
        }
iOS提供方法给web调用:
// 提供方法给web调用
func addJsObj(_ key: String, _ value: String) {
    wkwebview.evaluateJavaScript("vm.\(key) = \(value)", completionHandler: nil)
}

如果有更方便的写法欢迎来讨论,让我们一起有条不紊的持续进步。
喜欢的话不妨点个小小的赞与关注,您的赞与关注将是我源源不断的前进动力

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值