【uniapp-ios】App端与webview端相互通信的方法以及注意事项

前言

在开发中,使用uniapp开发的项目开发效率是极高的,使用一套代码就能够同时在多端上线,像笔者之前写过的使用Flutter端和webview端之间的相互通信方法和问题,这种方式本质上实际上是h5和h5之间的通信,网上有非常多的方案,最简单的就是使用postMessage和addEventListener的方式,这个在我之前的文章有讲解,这里不再赘述。

那么今天的问题,是使用uniapp开发的App端和H5端(webview)之间的通信问题

注意前提,是使用uniapp同时去开发app端和h5端。

问题

uniapp本质开发的app实际上还是web,那么能不能用postMessage的方式呢?

答案当然是可以的,但是你要区分情况,仔细看看官方文档

平台差异说明:App-nvue,是App-nvue的方法,这是个坑!!!

所以,这个时候就需要去区分情况了,你使用的是vue写的webview还是nvue写的webview

vue类型的webview

bash 复制代码
<web-view :src="src" ref="webview" :fullscreen="false" @message="receiveData"></web-view>

app传递数据给h5

本质:h5在webview环境中提取放入一个函数,app调用该函数传递数据进去。

h5端接收:可以在app.vue的onLaunch阶段

bash 复制代码
window.msgFromUniapp = (res) =>{
	console.log("原生传递过来的数据:",res)
}

app端发送:

bash 复制代码
		methods: {
			//给webview传递数据
			postMess(msg) {
				const currentWebview = this.$scope.$getAppWebview();
				const wv = currentWebview.children()[0];
				wv.evalJS(`msgFromUniapp('${JSON.stringify(msg)}')`)
			}
		},
		onLoad(item) {
			this.src = decodeURIComponent(item.url)
			// 传入需要跳转的链接 使用web-view标签进行跳转
			this.title = item.title
			// #ifdef APP-PLUS
			const currentWebview = this.$scope.$getAppWebview();
			const that = this
			setTimeout(function() {
				let wv = currentWebview.children()[0];
				that.postMess({
					type: 'app/systemInfo',
					data: {
						sys: 'ios'
					},
					code: 1,

				})
			}, 500);
			// #endif
		}

h5传递给app

app端接收:

添加监听即可

bash 复制代码
@message="receiveData"

h5端发送:

bash 复制代码
  //传递url给原生应用
          uni.webView.postMessage({
              data:{
                  action:'openUrl',
                  url:this.orderDetail.url
              }
          })

注意事项

app端要延迟再去获取webview实例,等webview加载完成。

官方写的是uni.posMessage,笔者亲试,没用的,注意是是 uni.webView.postMessage

nvue类型的webview

vue页面和nvue页面的区别,这里不做赘述,官方文档写的很清楚。

这个时候就可以使用官方文档的postMessage方式来

app传递数据给h5

绑定一个ref,获取webview实例

bash 复制代码
 <web-view ref="webview" :src="src" @onPostMessage="handlePostMessage"
      :style="{height:mbHeight,width:mbWidth,top:mbTop}" fullscreen="false"></web-view>
bash 复制代码
  this.$refs.webview.postMessage(data, '*')

或者

bash 复制代码
// 调用 webview 内部逻辑
			evalJs: function() {
				this.$refs.webview.evalJs("document.body.style.background ='#00FF00'");
			}
  • 然后h5使用window.addEventListener接收

h5传递数据给app

app接收消息:

bash 复制代码
<web-view ref="webview" class="webview" @onPostMessage="handlePostMessage"></web-view>
bash 复制代码
	handlePostMessage: function(data) {
				console.log("接收到消息:" + JSON.stringify(data.detail));
			},

注意事项

页面空白

如果你是nvue页面:

大概率是你没指定宽高,不信你放入一个百度的url试试,如果还是空白,请你设置style指定宽高。

如果你是vue页面,可能就是网页本身就打不开

环境问题

这是一个非常头疼的问题,我怎么知道这个web页面是在app环境打开还是在h5打开的,为什么需要去区分环境问题,因为你可能有一个这样的场景,你开发的app需要打开一个网页,然后撑满全屏,本质还是用webview容器去打开的,h5不知道自己所处的环境是app端,那么就会带来导航栏区域和底部安全区域怎么获取和处理的问题。

你可以选择从app端下手,前提是这个webview必须是nvue页面,因为vue页面默认webview是撑满全屏的,撑满全屏,撑满全屏。

如果你是vue页面,那么你可以通知h5端当前所处的环境,当前的导航栏高度和安全区域高度,在h5端单独去做样式兼容

如果你是nvue页面,除了上述方式,你还可以自己去指定webview的样式。

我还是建议都使用第一种方案吧,笔者自己去设置webview的样式发现在全屏阶段还是有一些问题的,不如默认撑满全屏,在h5端去做调整,毕竟调整h5端端成本最小,上架之后的app还需要提审等一些列步骤。

侧滑返回问题

可能有小伙伴发现,我打开一个webview,网页里面本身有好多跳转,为什么没办法侧滑返回。

原因是,本质上,在app端你打开的实际上只有一个webview页面,它只有一个页面,你的h5页面是在里面打开的,无论你h5的路由栈有多少层多没用,对于app来说,就只有一个webview页面。

所以,一定要注意放一个返回按钮提供给用户返回的机会,如果你要跳转外部网页,也不要用window.location去进行跳转,到时候就会返回不了了,你可以通知app端使用plus方法去打开网页

总结

官方文档并没有详细去区分两者的区别,网上的信息也很杂乱,所以在此特别去做区分和处理,如果你有更好的建议和方案,欢迎在评论区提出。

相关推荐
平凡シンプル2 小时前
安卓 uniapp跨端开发
android·uni-app
艾小逗3 小时前
uniapp快速入门教程,内容来源于官方文档,仅仅记录快速入门需要了解到的知识点
小程序·uni-app·app·es6
Magnetic_h16 小时前
【iOS】单例模式
笔记·学习·ui·ios·单例模式·objective-c
鸭子嘎鹅子呱18 小时前
uniapp使用高德地图设置marker标记点,后续根据接口数据改变某个marker标记点,动态更新
uni-app·map·高德地图
归辞...18 小时前
「iOS」——单例模式
ios·单例模式·cocoa
yanling202320 小时前
黑神话悟空mac可以玩吗
macos·ios·crossove·crossove24
归辞...1 天前
「iOS」viewController的生命周期
ios·cocoa·xcode
计算机源码社1 天前
分享一个基于微信小程序的居家养老服务小程序 养老服务预约安卓app uniapp(源码、调试、LW、开题、PPT)
android·微信小程序·uni-app·毕业设计项目·毕业设计源码·计算机课程设计·计算机毕业设计开题
Angus-zoe1 天前
uniapp+vue+微信小程序实现侧边导航
vue.js·微信小程序·uni-app
Pluto & Ethereal1 天前
uni-app尺寸单位、flex布局于背景图片
uni-app