
没有mac?在Windows上传ipa 使用XUploader
使用 XUploader 在Windows(实体机或云主机中)上传 ipa 包到App Store Connect开发者后台
!
1.下载工具XUploader
前往 www.xbeautybay.com 下载windows版

下载Windows版本
2.解压并运行exe
解压下载的压缩包,释放出exe文件并运行
注意:点击运行时系统会提示风险,略过,点击仍然运行(英文系统点击Run any way)
点击更多信息
点击仍然运行
3.填写必要信息
填写开发者账号、专用密码、授权码
选择需要上传的ipa文件(注意文件名中不能包含特殊字符或空格,同时不能上传后台已经上传过的build,每次打包build要 1,否则App Store Connect会验证不通过)
4.点击开始上传按钮
等待日志输出窗口输出上传成功即可
5.登录App Store Connect开发者后台
在testflight查看ipa处理情况,如果处于处理中则等待处理完成即可在提交界面选取build,如果消失了请检查开发者账号绑定的邮件,会有相关提示说明,按说明修复重新打包再次上传即可。
处理成功,可在提交界面选取该build
使用 XUploader 在Windows(实体机或云主机中)上传 ipa 包到App Store Connect开发者后台
!
1.下载工具XUploader
前往 www.xbeautybay.com 下载windows版
下载Windows版本
2.解压并运行exe
解压下载的压缩包,释放出exe文件并运行
注意:点击运行时系统会提示风险,略过,点击仍然运行(英文系统点击Run any way)
点击更多信息
点击仍然运行
3.填写必要信息
填写开发者账号、专用密码、授权码
选择需要上传的ipa文件(注意文件名中不能包含特殊字符或空格,同时不能上传后台已经上传过的build,每次打包build要 1,否则App Store Connect会验证不通过)
4.点击开始上传按钮
等待日志输出窗口输出上传成功即可
5.登录App Store Connect开发者后台
在testflight查看ipa处理情况,如果处于处理中则等待处理完成即可在提交界面选取build,如果消失了请检查开发者账号绑定的邮件,会有相关提示说明,按说明修复重新打包再次上传即可。
处理成功,可在提交界面选取该build
收起阅读 »
vue3+vite5网页聊天模板|vite5.x+element-plus仿微信
vite5-webchat使用最新前端技术vite5+vue3+vue-router+pinia+sass+element-plus搭建网页端聊天系统。实现了聊天、通讯录、朋友圈、短视频、我的等功能模块。支持收缩侧边栏、背景壁纸换肤、锁屏、最大化等功能。
vite-wechat使用vite5.x构建工具搭建项目模板,采用vue3 setup语法开发。
技术栈
- 开发工具:Vscode
- 技术框架:Vite5.2+Vue3.4+vue-router4.3+Pinia2
- UI组件库:element-plus^2.7.5 (饿了么网页端vue3组件库)
- 状态管理:pinia^2.1.7
- 地图插件:@amap/amap-jsapi-loader(高德地图组件)
- 视频滑动:swiper^11.1.4
- 图文编辑器:wangeditor^4.7.15(笔记/朋友圈文本编辑器)
- 样式编译:sass^1.77.4
- 构建工具:vite^5.2.0
前段时间有分享一篇flutter3.x桌面端仿微信EXE聊天,感兴趣的可以去看看。
https://segmentfault.com/a/1190000044675519
项目结构
vite-chat聊天已经同步到我的最新原创作品集,有需要的可以去看看。
https://gf.bilibili.com/item/detail/1106226011
import { createApp } from 'vue'
import './style.scss'
import App from './App.vue'
// 引入组件库
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import VEPlus from 've-plus'
import 've-plus/dist/ve-plus.css'
// 引入路由/状态管理
import Router from './router'
import Pinia from './pinia'
const app = createApp(App)
app
.use(ElementPlus)
.use(VEPlus)
.use(Router)
.use(Pinia)
.mount('#app')
项目布局模板
<template>
<div class="vu__container" :style="{'--themeSkin': appstate.config.skin}">
<div class="vu__layout">
<div class="vu__layout-body">
<!-- 菜单栏 -->
<slot v-if="!route?.meta?.hideMenuBar" name="menubar">
<MenuBar />
</slot>
<!-- 侧边栏 -->
<div v-if="route?.meta?.showSideBar" class="vu__layout-sidebar" :class="{'hidden': appstate.config.collapsed}">
<aside class="vu__layout-sidebar__body flexbox flex-col">
<slot name="sidebar">
<SideBar />
</slot>
<!-- 折叠按钮 -->
<Collapse />
</aside>
</div>
<!-- 主内容区 -->
<div class="vu__layout-main flex1 flexbox flex-col">
<Winbtn v-if="!route?.meta?.hideWinBar" />
<router-view v-slot="{ Component, route }">
<keep-alive>
<component :is="Component" :key="route.path" />
</keep-alive>
</router-view>
</div>
</div>
</div>
</div>
</template>
vue3-chat短视频模块
<!-- 短视频模块 -->
<div class="vu__video-container">
<!-- tabs操作栏 -->
<div class="vu__video-tabswrap flexbox">
<el-tabs v-model="activeName" class="vu__video-tabs">
<el-tab-pane label="关注" name="attention" />
<el-tab-pane label="推荐" name="recommend" />
</el-tabs>
</div>
<swiper-container
class="vu__swiper"
direction="vertical"
:speed="150"
:grabCursor="true"
:mousewheel="{invert: true}"
@swiperslidechange="onSlideChange"
>
<swiper-slide v-for="(item, index) in videoList" :key="index">
<!-- 视频层 -->
<video
class="vu__player"
:id="'' + index"
:src="item.src"
:poster="item.poster"
loop
preload="auto"
:autoplay="index == currentVideo"
webkit-playsinline="true"
x5-video-player-type="h5-page"
x5-video-player-fullscreen="true"
playsinline
@click="handleVideoClicked"
>
</video>
<div v-if="!isPlaying" class="vu__player-btn" @click="handleVideoClicked"></div>
<!-- 右侧操作栏 -->
<div class="vu__video-toolbar">
...
</div>
<!-- 底部信息区域 -->
<div class="vu__video-footinfo flexbox flex-col">
<div class="name">@{{item.author}}</div>
<div class="content">{{item.desc}}</div>
</div>
</swiper-slide>
</swiper-container>
<!-- ///底部进度条 -->
<el-slider class="vu__video-progressbar" v-model="progressBar" @input="handleSlider" @change="handlePlay" />
<div v-if="isDraging" class="vu__video-duration">{{videoTime}} / {{videoDuration}}</div>
</div>
vue3聊天功能
<template>
<!-- 顶部导航 -->
...
<!-- 内容区 -->
<div class="vu__layout-main__body">
<Scrollbar ref="scrollRef" autohide gap="2">
<!-- 渲染聊天内容 -->
<div class="vu__chatview" @dragenter="handleDragEnter" @dragover="handleDragOver" @drop="handleDrop">
...
</div>
</Scrollbar>
</div>
<!-- 底部操作栏 -->
<div class="vu__footview">
<div class="vu__toolbar flexbox">
...
</div>
<div class="vu__editor">
<Editor ref="editorRef" v-model="editorValue" @paste="handleEditorPaste" />
</div>
<div class="vu__submit">
<button @click="handleSubmit">发送(S)</button>
</div>
</div>
...
</template>
综上就是vue3+vite5实战开发仿微信聊天系统一些知识分享,希望对大家有些帮助~
作者:xiaoyan2017
链接: https://segmentfault.com/a/1190000044984067
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
vite5-webchat使用最新前端技术vite5+vue3+vue-router+pinia+sass+element-plus搭建网页端聊天系统。实现了聊天、通讯录、朋友圈、短视频、我的等功能模块。支持收缩侧边栏、背景壁纸换肤、锁屏、最大化等功能。
vite-wechat使用vite5.x构建工具搭建项目模板,采用vue3 setup语法开发。
技术栈
- 开发工具:Vscode
- 技术框架:Vite5.2+Vue3.4+vue-router4.3+Pinia2
- UI组件库:element-plus^2.7.5 (饿了么网页端vue3组件库)
- 状态管理:pinia^2.1.7
- 地图插件:@amap/amap-jsapi-loader(高德地图组件)
- 视频滑动:swiper^11.1.4
- 图文编辑器:wangeditor^4.7.15(笔记/朋友圈文本编辑器)
- 样式编译:sass^1.77.4
- 构建工具:vite^5.2.0
前段时间有分享一篇flutter3.x桌面端仿微信EXE聊天,感兴趣的可以去看看。
https://segmentfault.com/a/1190000044675519
项目结构
vite-chat聊天已经同步到我的最新原创作品集,有需要的可以去看看。
https://gf.bilibili.com/item/detail/1106226011
import { createApp } from 'vue'
import './style.scss'
import App from './App.vue'
// 引入组件库
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import VEPlus from 've-plus'
import 've-plus/dist/ve-plus.css'
// 引入路由/状态管理
import Router from './router'
import Pinia from './pinia'
const app = createApp(App)
app
.use(ElementPlus)
.use(VEPlus)
.use(Router)
.use(Pinia)
.mount('#app')
项目布局模板
<template>
<div class="vu__container" :style="{'--themeSkin': appstate.config.skin}">
<div class="vu__layout">
<div class="vu__layout-body">
<!-- 菜单栏 -->
<slot v-if="!route?.meta?.hideMenuBar" name="menubar">
<MenuBar />
</slot>
<!-- 侧边栏 -->
<div v-if="route?.meta?.showSideBar" class="vu__layout-sidebar" :class="{'hidden': appstate.config.collapsed}">
<aside class="vu__layout-sidebar__body flexbox flex-col">
<slot name="sidebar">
<SideBar />
</slot>
<!-- 折叠按钮 -->
<Collapse />
</aside>
</div>
<!-- 主内容区 -->
<div class="vu__layout-main flex1 flexbox flex-col">
<Winbtn v-if="!route?.meta?.hideWinBar" />
<router-view v-slot="{ Component, route }">
<keep-alive>
<component :is="Component" :key="route.path" />
</keep-alive>
</router-view>
</div>
</div>
</div>
</div>
</template>
vue3-chat短视频模块
<!-- 短视频模块 -->
<div class="vu__video-container">
<!-- tabs操作栏 -->
<div class="vu__video-tabswrap flexbox">
<el-tabs v-model="activeName" class="vu__video-tabs">
<el-tab-pane label="关注" name="attention" />
<el-tab-pane label="推荐" name="recommend" />
</el-tabs>
</div>
<swiper-container
class="vu__swiper"
direction="vertical"
:speed="150"
:grabCursor="true"
:mousewheel="{invert: true}"
@swiperslidechange="onSlideChange"
>
<swiper-slide v-for="(item, index) in videoList" :key="index">
<!-- 视频层 -->
<video
class="vu__player"
:id="'' + index"
:src="item.src"
:poster="item.poster"
loop
preload="auto"
:autoplay="index == currentVideo"
webkit-playsinline="true"
x5-video-player-type="h5-page"
x5-video-player-fullscreen="true"
playsinline
@click="handleVideoClicked"
>
</video>
<div v-if="!isPlaying" class="vu__player-btn" @click="handleVideoClicked"></div>
<!-- 右侧操作栏 -->
<div class="vu__video-toolbar">
...
</div>
<!-- 底部信息区域 -->
<div class="vu__video-footinfo flexbox flex-col">
<div class="name">@{{item.author}}</div>
<div class="content">{{item.desc}}</div>
</div>
</swiper-slide>
</swiper-container>
<!-- ///底部进度条 -->
<el-slider class="vu__video-progressbar" v-model="progressBar" @input="handleSlider" @change="handlePlay" />
<div v-if="isDraging" class="vu__video-duration">{{videoTime}} / {{videoDuration}}</div>
</div>
vue3聊天功能
<template>
<!-- 顶部导航 -->
...
<!-- 内容区 -->
<div class="vu__layout-main__body">
<Scrollbar ref="scrollRef" autohide gap="2">
<!-- 渲染聊天内容 -->
<div class="vu__chatview" @dragenter="handleDragEnter" @dragover="handleDragOver" @drop="handleDrop">
...
</div>
</Scrollbar>
</div>
<!-- 底部操作栏 -->
<div class="vu__footview">
<div class="vu__toolbar flexbox">
...
</div>
<div class="vu__editor">
<Editor ref="editorRef" v-model="editorValue" @paste="handleEditorPaste" />
</div>
<div class="vu__submit">
<button @click="handleSubmit">发送(S)</button>
</div>
</div>
...
</template>
综上就是vue3+vite5实战开发仿微信聊天系统一些知识分享,希望对大家有些帮助~
作者:xiaoyan2017
链接: https://segmentfault.com/a/1190000044984067
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Vue H5网页唤起基于uniapp开发的app应用如果未安装则下载安装
1、App配置 scheme 标识(安卓和ios尽量配置成一样的名称)
1.1、如果只是唤起app则可以直接打包自定义基座
1.2、如果需要唤起指定的app页面,如打开商品详情,则需要完成第6步再进行打包操作
2、下载安装callapp-lib 下载命令 npm install callapp-lib -S
3、引入 callapp-lib 插件 import CallApp from "callapp-lib";
4、配置 相关参数
const arouseAPP = () => {
const options = {
scheme: {
protocol: "", //ios schema标识
},
intent: {
//打开安卓标识
package: "com.tencent.mm", //安卓协议 com.tencent.mm(应用包名)
scheme: "",
},
appstore: '', //App Store地址
yingyongbao: '', //应用宝地址
timeout: 3000, //等待唤端的时间(单位: ms),超时则判断为唤端失败。
};
const callLib = new CallApp(options);
callLib.open({
path: "pages/index/productDetail/productDetail",//打开App指定页面(页面路径,不打开指定页面就不填)
param: {
id: productId //打开App页面携带的参数
},
fallback: function () {
console.warn("警告-------------:唤起APP失败");
//打不开具体处理
},
});
};
5、App端被唤起后跳转逻辑需要处理一下
1、App配置 scheme 标识(安卓和ios尽量配置成一样的名称)
1.1、如果只是唤起app则可以直接打包自定义基座
1.2、如果需要唤起指定的app页面,如打开商品详情,则需要完成第6步再进行打包操作
2、下载安装callapp-lib 下载命令 npm install callapp-lib -S
3、引入 callapp-lib 插件 import CallApp from "callapp-lib";
4、配置 相关参数
const arouseAPP = () => {
const options = {
scheme: {
protocol: "", //ios schema标识
},
intent: {
//打开安卓标识
package: "com.tencent.mm", //安卓协议 com.tencent.mm(应用包名)
scheme: "",
},
appstore: '', //App Store地址
yingyongbao: '', //应用宝地址
timeout: 3000, //等待唤端的时间(单位: ms),超时则判断为唤端失败。
};
const callLib = new CallApp(options);
callLib.open({
path: "pages/index/productDetail/productDetail",//打开App指定页面(页面路径,不打开指定页面就不填)
param: {
id: productId //打开App页面携带的参数
},
fallback: function () {
console.warn("警告-------------:唤起APP失败");
//打不开具体处理
},
});
};
5、App端被唤起后跳转逻辑需要处理一下

uni-grid第二次进入样式问题
uni-grid组件第一次进入正常,第二次进入就挤成一排了。
解决办法
- 如果你不需要边框,直接在组件上加上:show-border="false"即可
- 如果你需要边框的情况下有两种解决办法
第一,给uni-grid组件外层的view组件加固定宽度,很显然这种办法只能解决一个端的问题,如需多端运行,看第二种办法;
第二,修改uni-grid组件中的uni-grid 类样式,添加width:100%;即可,这个应该是该组件的一个小bug
uni-grid组件第一次进入正常,第二次进入就挤成一排了。
解决办法
- 如果你不需要边框,直接在组件上加上:show-border="false"即可
- 如果你需要边框的情况下有两种解决办法
第一,给uni-grid组件外层的view组件加固定宽度,很显然这种办法只能解决一个端的问题,如需多端运行,看第二种办法;
第二,修改uni-grid组件中的uni-grid 类样式,添加width:100%;即可,这个应该是该组件的一个小bug

Android抓包配置
1、创建network_security_config.xml文件,并将其拷贝到应用资源nativeResources\android\res\xml目录下
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</base-config>
</network-security-config>
2、创建AndroidManifest.template.xml文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
package="你自己的包名">
<!-- 信任用户证书,用于非生产环境抓包 -->
<application android:networkSecurityConfig="@xml/network_security_config">
</application>
</manifest>
3、修改vue.config.js或vite.config.js
const fs = require('fs');
const path = require('path');
const templateFilePath = path.join(__dirname, 'AndroidManifest.template.xml');
const outputFilePath = path.join(__dirname, 'AndroidManifest.xml');
const config = require('./config.js')
// #ifdef APP
// 非生产环境,添加网络安全配置,用于抓包
if(config.env !== 'prod'){
fs.copyFileSync(templateFilePath, outputFilePath);
}else if(fs.existsSync(outputFilePath)){
fs.unlinkSync(outputFilePath)
}
// #endif
4、下载抓包工具Reqable
下载地址:https://reqable.com/zh-CN/download
1、创建network_security_config.xml文件,并将其拷贝到应用资源nativeResources\android\res\xml目录下
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
<certificates src="user" />
</trust-anchors>
</base-config>
</network-security-config>
2、创建AndroidManifest.template.xml文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
package="你自己的包名">
<!-- 信任用户证书,用于非生产环境抓包 -->
<application android:networkSecurityConfig="@xml/network_security_config">
</application>
</manifest>
3、修改vue.config.js或vite.config.js
const fs = require('fs');
const path = require('path');
const templateFilePath = path.join(__dirname, 'AndroidManifest.template.xml');
const outputFilePath = path.join(__dirname, 'AndroidManifest.xml');
const config = require('./config.js')
// #ifdef APP
// 非生产环境,添加网络安全配置,用于抓包
if(config.env !== 'prod'){
fs.copyFileSync(templateFilePath, outputFilePath);
}else if(fs.existsSync(outputFilePath)){
fs.unlinkSync(outputFilePath)
}
// #endif
4、下载抓包工具Reqable
下载地址:https://reqable.com/zh-CN/download

唤醒锁
// 在uniapp中调用原生API启用唤醒锁
function enableWakeLock() {
// 判断当前环境是否支持
if (plus.os.name.toLowerCase() === 'android') {
// 尝试获取唤醒锁
var wakeLock = plus.android.invoke('android.os.PowerManager', 'newWakeLock', plus.android.getContext().POWER_SERVICE);
if (wakeLock) {
// 获取到唤醒锁后,设置为不释放锁的标志位,即保持屏幕常亮
wakeLock.setReferenceCounted(false);
wakeLock.acquire();
console.log('Wake lock acquired');
} else {
console.log('Failed to acquire wake lock');
}
} else {
console.log('Wake lock feature is only supported on Android devices');
}
}
// 在适当的时候释放唤醒锁,比如用户离开应用时
function releaseWakeLock() {
if (wakeLock && plus.os.name.toLowerCase() === 'android') {
wakeLock.release();
console.log('Wake lock released');
}
}
// 在适当的时候调用enableWakeLock函数来启用唤醒锁
2.方法
// 判断是否为Android平台
if (plus.os.name.toLowerCase() === 'android') {
// 获取当前的Activity
var main = plus.android.runtimeMainActivity();
var Window = plus.android.importClass('android.view.Window');
var PowerManager = plus.android.importClass('android.os.PowerManager');
// 获取PowerManager服务
var pm = main.getSystemService(Window.POWER_SERVICE);
var wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, 'my_wakelock_tag');
// 启用wakelock
wl.acquire();
// 在需要关闭wakelock的时候,调用release方法
// wl.release();
}
// 在uniapp中调用原生API启用唤醒锁
function enableWakeLock() {
// 判断当前环境是否支持
if (plus.os.name.toLowerCase() === 'android') {
// 尝试获取唤醒锁
var wakeLock = plus.android.invoke('android.os.PowerManager', 'newWakeLock', plus.android.getContext().POWER_SERVICE);
if (wakeLock) {
// 获取到唤醒锁后,设置为不释放锁的标志位,即保持屏幕常亮
wakeLock.setReferenceCounted(false);
wakeLock.acquire();
console.log('Wake lock acquired');
} else {
console.log('Failed to acquire wake lock');
}
} else {
console.log('Wake lock feature is only supported on Android devices');
}
}
// 在适当的时候释放唤醒锁,比如用户离开应用时
function releaseWakeLock() {
if (wakeLock && plus.os.name.toLowerCase() === 'android') {
wakeLock.release();
console.log('Wake lock released');
}
}
// 在适当的时候调用enableWakeLock函数来启用唤醒锁
2.方法
// 判断是否为Android平台
if (plus.os.name.toLowerCase() === 'android') {
// 获取当前的Activity
var main = plus.android.runtimeMainActivity();
var Window = plus.android.importClass('android.view.Window');
var PowerManager = plus.android.importClass('android.os.PowerManager');
// 获取PowerManager服务
var pm = main.getSystemService(Window.POWER_SERVICE);
var wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, 'my_wakelock_tag');
// 启用wakelock
wl.acquire();
// 在需要关闭wakelock的时候,调用release方法
// wl.release();
}

支持文字,图片,文件。视频。语音通话,视频通话吗? 如果支持,在那几个端支持?比如H5,小程序,安卓,IOS
支持文字,图片,文件。视频。语音通话,视频通话吗?
如果支持,在那几个端支持?比如H5,小程序,安卓,IOS
支持文字,图片,文件。视频。语音通话,视频通话吗?
如果支持,在那几个端支持?比如H5,小程序,安卓,IOS

app使用webview嵌入h5,h5和app通信或者在操作后自动返回app
第一:首先下载官方最新的uni.webview.js,下载链接在这儿找 官方文档
第二:将下载好的webview.js放在h5的static文件夹下,
第三:在h5的index.html引入,然后写如下代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
<script type="text/javascript" src="./static/webview.js"></script>
<script type="text/javascript" >
const webViewJs = uni.webView
console.log('webViewJs',webViewJs);
</script>
</body>
</html>
在vue文件使用webviewjs返回app或者和app通信,vue代码如下
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<button type="primary" @click="back">返回app</button>
<button type="primary" @click="sendMsg">发消息给app</button>
<button type="primary" @click="toIndex">跳转到app首页</button>
</view>
</template>
<script>
export default {
data() {
return {
title: 'Hello'
};
},
onLoad() {},
methods: {
back() {
webViewJs.navigateBack();
},
sendMsg(){
webViewJs.postMessage({
data: {
action: 'postMessage'
}
});
},
toIndex(){
webViewJs.navigateTo({
url:'/pages/index/index'
})
// 如果是tabar,使用switchTab跳转
// webViewJs.switchTab({
// url:'/pages/index/index'
// })
}
}
};
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
button {
margin: 20rpx;
}
</style>
app的webview页面接收h5传过来的值,代码如下
<template>
<view class="content">
<web-view src="http://localhost:5173/" @message="onMessage"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
};
},
methods: {
onMessage(e){
console.log('e',e.detail.data);
}
}
};
</script>
<style lang="scss" scoped>
</style>
第一:首先下载官方最新的uni.webview.js,下载链接在这儿找 官方文档
第二:将下载好的webview.js放在h5的static文件夹下,
第三:在h5的index.html引入,然后写如下代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
<script type="text/javascript" src="./static/webview.js"></script>
<script type="text/javascript" >
const webViewJs = uni.webView
console.log('webViewJs',webViewJs);
</script>
</body>
</html>
在vue文件使用webviewjs返回app或者和app通信,vue代码如下
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<button type="primary" @click="back">返回app</button>
<button type="primary" @click="sendMsg">发消息给app</button>
<button type="primary" @click="toIndex">跳转到app首页</button>
</view>
</template>
<script>
export default {
data() {
return {
title: 'Hello'
};
},
onLoad() {},
methods: {
back() {
webViewJs.navigateBack();
},
sendMsg(){
webViewJs.postMessage({
data: {
action: 'postMessage'
}
});
},
toIndex(){
webViewJs.navigateTo({
url:'/pages/index/index'
})
// 如果是tabar,使用switchTab跳转
// webViewJs.switchTab({
// url:'/pages/index/index'
// })
}
}
};
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
button {
margin: 20rpx;
}
</style>
app的webview页面接收h5传过来的值,代码如下
<template>
<view class="content">
<web-view src="http://localhost:5173/" @message="onMessage"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
};
},
methods: {
onMessage(e){
console.log('e',e.detail.data);
}
}
};
</script>
<style lang="scss" scoped>
</style>
收起阅读 »

关于上架vivo应用市场隐私不合规并提示在静默、后台状态下,APP存在收集“OAID”等信息的行为。
关于上架vivo应用市场隐私不合规并提示在静默、后台状态下,APP存在收集“OAID”等信息的行为。参考:
APP在运行时,存在以下违规行为:
1、未见向用户告知且未经用户同意,在静默、后台状态下,APP存在收集“OAID”等信息的行为,非服务所必需且无合理应用场景,超出与收集个人信息时所声称的目的具有直接或合理关联范围
首先需要明确DCloud不会在后台或静默状态下违规收集任何信息。
经过与按照本文档修改之后但是隐私检测仍然不通过的开发者交流,目前确认是vivo的应用安全检测平台
的误报。以下是vivo客服给到的回复。
由于涉及到vivo的内部流程,具体问题及原因vivo并没有对我们透露。
如果已经按照本文档修改之后提交检测仍然提示APP请求携带OAID
的,可以直接联系vivo的人工客服或者发送邮件到open@vivo.com
。
针对上述问题,目前已经确定的情况有:
1. uniCloud请求携带OAID
如果使用了uniCloud的话,云函数的头信息会包含getSystemInfo里的值,所以也包含了oaid,但这个是发送到你的uniCloud服务器地址的,不是发给DCloud服务器。
但因为每次uniCloud请求都会发送,触发了vivo提到的频繁采集采集。
在头信息里包含太多getSystemInfo信息确实没必要。目前已经发布了HBuilderX 4.21版本,请升级后重现打包。
新版默认减少了头信息内容,然后给开发者提供自定义uniCloud头信息的方式。
不想升级的用户,也可以用下面的临时方案,将附件内的文件替换到HBuilderX的如下位置:HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/uni-cloud/dist/index.js 重新打包。
注意:需要先升级到最新的HBuilderX之后按照上述内容替换文件,最后重新打包。
如果oaid对你比较重要,头信息里的oaid在你的业务中被你使用了,还有一种策略,是配置安全网络,这会让app和uniCloud之间的所有传输数据加密。也可以阻止三方识别。
2. uni统计会上报oaid
如果你的app开启了uni统计1,访问域名是tongji.dcloud.io。也会上报oaid。如果想准确统计有多少用户设备,那么oaid是不可或缺的。
目前的可选方案有:
- 先在manifest里去掉uni统计1,然后打包apk,把新的apk提交给vivo试一下。暂时放弃vivo上的统计数据。
- 改用uni统计2
- 和vivo客服pk。见上图聊天记录,vivo承认检测有误。
3. 个推
HBuilder X于4.11版升级过个推SDK,解决了在静默状态下频繁手机隐私信息的问题。
请确保提测的安装包版本是用HBuilder X 4.11之后的版本提交打包的。
另外注意一键登陆也是个推的。
如果堆栈信息表中的代码所属
字段仍然存在个推,可以微信扫码联系个推客服。
4. 其他SDK或者原生插件
针对其他SDK或者原生插件,可以参考堆栈信息表中的代码所属
字段联系对应的SDK公司。
比如有的堆栈里显示了友盟的sdk,再比如使用了原生插件,需要排查这些原生插件的行为。
- 最后也需要注意自己的隐私协议
如果给自己的服务器(不管是不是uniCloud)发送敏感设备信息,需要在隐私协议里披露清楚。
使用三方sdk时,检测到有堆栈调用,不代表有问题。只要隐私协议写清楚,也是允许三方sdk采集的,只是要注意频繁采集的问题。
关于上架vivo应用市场隐私不合规并提示在静默、后台状态下,APP存在收集“OAID”等信息的行为。参考:
APP在运行时,存在以下违规行为:
1、未见向用户告知且未经用户同意,在静默、后台状态下,APP存在收集“OAID”等信息的行为,非服务所必需且无合理应用场景,超出与收集个人信息时所声称的目的具有直接或合理关联范围
首先需要明确DCloud不会在后台或静默状态下违规收集任何信息。
经过与按照本文档修改之后但是隐私检测仍然不通过的开发者交流,目前确认是vivo的应用安全检测平台
的误报。以下是vivo客服给到的回复。
由于涉及到vivo的内部流程,具体问题及原因vivo并没有对我们透露。
如果已经按照本文档修改之后提交检测仍然提示APP请求携带OAID
的,可以直接联系vivo的人工客服或者发送邮件到open@vivo.com
。
针对上述问题,目前已经确定的情况有:
1. uniCloud请求携带OAID
如果使用了uniCloud的话,云函数的头信息会包含getSystemInfo里的值,所以也包含了oaid,但这个是发送到你的uniCloud服务器地址的,不是发给DCloud服务器。
但因为每次uniCloud请求都会发送,触发了vivo提到的频繁采集采集。
在头信息里包含太多getSystemInfo信息确实没必要。目前已经发布了HBuilderX 4.21版本,请升级后重现打包。
新版默认减少了头信息内容,然后给开发者提供自定义uniCloud头信息的方式。
不想升级的用户,也可以用下面的临时方案,将附件内的文件替换到HBuilderX的如下位置:HBuilderX/plugins/uniapp-cli/node_modules/@dcloudio/vue-cli-plugin-uni/packages/uni-cloud/dist/index.js 重新打包。
注意:需要先升级到最新的HBuilderX之后按照上述内容替换文件,最后重新打包。
如果oaid对你比较重要,头信息里的oaid在你的业务中被你使用了,还有一种策略,是配置安全网络,这会让app和uniCloud之间的所有传输数据加密。也可以阻止三方识别。
2. uni统计会上报oaid
如果你的app开启了uni统计1,访问域名是tongji.dcloud.io。也会上报oaid。如果想准确统计有多少用户设备,那么oaid是不可或缺的。
目前的可选方案有:
- 先在manifest里去掉uni统计1,然后打包apk,把新的apk提交给vivo试一下。暂时放弃vivo上的统计数据。
- 改用uni统计2
- 和vivo客服pk。见上图聊天记录,vivo承认检测有误。
3. 个推
HBuilder X于4.11版升级过个推SDK,解决了在静默状态下频繁手机隐私信息的问题。
请确保提测的安装包版本是用HBuilder X 4.11之后的版本提交打包的。
另外注意一键登陆也是个推的。
如果堆栈信息表中的代码所属
字段仍然存在个推,可以微信扫码联系个推客服。
4. 其他SDK或者原生插件
针对其他SDK或者原生插件,可以参考堆栈信息表中的代码所属
字段联系对应的SDK公司。
比如有的堆栈里显示了友盟的sdk,再比如使用了原生插件,需要排查这些原生插件的行为。
- 最后也需要注意自己的隐私协议
如果给自己的服务器(不管是不是uniCloud)发送敏感设备信息,需要在隐私协议里披露清楚。
使用三方sdk时,检测到有堆栈调用,不代表有问题。只要隐私协议写清楚,也是允许三方sdk采集的,只是要注意频繁采集的问题。
收起阅读 »