当前位置: 首页 > news >正文

苏州企业网站制作报价国外好的室内设计网站

苏州企业网站制作报价,国外好的室内设计网站,郝友做的网站,做网站的如何找业务目录 前言 一、项目初始化 1.初始化方式 2.账号注册 3.插件安装 二、项目结构及重点文件介绍 1.项目基本结构 2.项目文件介绍 三、应用打包 1. 安卓打包 2.苹果打包 四、应用发布 1. 安卓市场发布 用户权限和隐私政策 注销 软著和App备案证书 2. 苹果市场发布 … 目录 前言 一、项目初始化 1.初始化方式 2.账号注册 3.插件安装 二、项目结构及重点文件介绍 1.项目基本结构 2.项目文件介绍 三、应用打包 1. 安卓打包 2.苹果打包 四、应用发布 1. 安卓市场发布 用户权限和隐私政策 注销 软著和App备案证书 2. 苹果市场发布 五、开发过程中的坑及解决方案 1. 消息推送uni-push2 2. 微信审核 3. 全屏遮罩 4. 状态栏高度 5. 应用更新 6. 清除缓存 7. webview 8. 分享 9. 地图 10. 访问量统计 11. 隐私政策 12. Universal Links 13. 模拟器 14. 通过外部链接打开App并跳转到目标页面 15.网络状态监测 16.路由拦截 17.请求封装 18.UrlSchemes 总结  前言 通过uniapp官方开发文档可以完成app开发但开发过程中难免遇到疑难杂症以下是本人开发过程中遇到的各种问题及应对方式仅供参考。 一、项目初始化 1.初始化方式 首次初始化项目过程详见uniapp官方文档。uni-app官网 2.账号注册 uniapp开发需要在Dcloud上注册一个账号账号用于项目打包发布、云服务相关。最好在项目开始之前就把账号申请好如果是企业项目开发就要公司申请一个账号避免后期应用转让比较麻烦。使用云服务是需要交费的比如消息推送、版本更新等等按流量收费。可以申请一个月的免费云空间到期后可以继续申请一个月的免费云空间。Dcloud注册地址开发者中心 3.插件安装 HBuilderX开发工具自带一些官方插件如git相关、代码格式化相关、云打包相关、真机运行相关、内置浏览器运行相关能装的都装上。安装方式为点击HBuilderX上方的“工具”——“插件安装” 二、项目结构及重点文件介绍 1.项目基本结构 项目初始化之后基本目录文件如下 2.项目文件介绍 uniCloud项目初始化时是没有这个目录的但是如果项目中需要使用云服务比如需要使用云函数、应用版本管理与更新、消息推送等就需要通过相关操作创建此目录下文有详细说明。 .hbuilderx当项目引入云服务时会自动创建此目录该目录下存在一个launch.json文件文件中内容主要是配置云函数的连接方式比如是本地调用还是连接云服务调用。 api该目录是自己创建的用于存放调用后端接口的js文件可以根据自己的项目判断是否需要创建此目录非必要。 common用于存放全局通用文件。 components用于存放全局通用组件。 pages用于存放页面文件一般是.vue文件和.nvue文件。 static用于存放静态资源文件比如图片文件、字体文件等。 uni_modules存放uniapp插件插件可在官网下载并直接安装。该目录自动生成。 unpackage存放非代码资源不需要上传到代码管理工具。该目录自动生成。 androidPrivacy.json隐私条款文件在安卓手机生效。效果是当app首次打开时在进入主页面之前系统会自动弹出隐私条款询问用户是否同意同意后才会进入到app中。该功能用于安卓应用市场审核无此隐私条款无法上架安卓应用市场。苹果商店没有这些臭毛病。 apple-app-site-association配置苹果Universal Link使用户在浏览器中输入配置的ulink地址后可以看到打开应用的提示。 manifest.jsonapp配置项文件支持界面配置和源码配置两种方式。 三、应用打包 1. 安卓打包 HBuilder提供了云打包方式在开发工具中点击发行-原生App-云打包即可进入打包界面。安卓app打包需要Android证书生成证书的方式见官方提供的链接 Android平台签名证书(.keystore)生成指南 - DCloud问答 生成证书后即可在打包页面进行打包了需要上传证书填写证书别名、私钥密码这些东西在生成证书的时候已经填写过需要记下来每次打包都需要用到。 打包界面有一个渠道包的选项意思是如果需要在不同的安卓平台发布并且统计不同平台的下载量的话可以勾选对应的渠道打包后会打出对应的渠道包发布在相应的应用市场。 最后打包有传统打包和安心打包两种选择区别就是是否将源码上传到Hbuilder平台上。我选的是安心打包不需要上传代码。 打包成功后会在文件目录的unpackage/release/apk目录下生成本次打包的apk文件。 2.苹果打包 苹果打包过程与安卓打包过程相同主要是生成证书的方式不同另苹果打包要在mac上进行。 苹果证书分为开发证书和发布证书另外还有对应的描述文件。生成证书和描述文件的方法见官网提供的链接iOS证书(.p12)和描述文件(.mobileprovision)申请 - DCloud问答 拿到证书和描述文件后即可打包。使用开发证书打出的包只能用于测试不能发布应用市场使用发布证书打出的包可以发布应用市场。此外如果想在手机里使用测试包需要将测试手机的udid加入到开发证书对应的描述文件中在生成描述文件时有这一步的配置  四、应用发布 1. 安卓市场发布 安卓应用市场常见的有华为、小米、OPPO、VIVO、应用宝等等发布前需要到各个应用市场注册账号填写相关资料提交审核即可。 注意点 用户权限和隐私政策 安卓应用市场审核比较严格尤其对用户权限、隐私政策等等要求比较高。对于用户权限和隐私问题一定要清清楚楚的写明应用索要了哪些权限引用了哪些SDK涉及到哪些用户隐私只要说明合理一定会审核过的不要试图隐瞒瞒不住。 安卓市场对隐私政策比较执着要求进入App之前要先弹出隐私政策窗口只有用户同意隐私政策之后才能进入应用。此外有些应用市场对隐私政策特别执着不仅要有链接地址可以进入隐私政策查看还有在应用内部有随时可以查看隐私政策地方。 注销 有些应用市场要求应用必须提供注销功能所以该功能必须提供。 软著和App备案证书 应用发布需要软著证书软著证书可以是实体软著的扫描件也可以是电子版软著证书实体软著和电子版软著不是一个东西电子软著下证比较快。App备案证书是2023年9月工信部新要求到相关部门备案即可。 2. 苹果市场发布 苹果市场发布相对简单官方仅需要一个软著证明电子版即可另外如果应用中索要用户的哪些权限也需要说明。对隐私条款等内容没有明确要求。应用截图要与应用实际页面内容保持一致否则也会审核不过。 苹果对应用外的第三方内容审查比较严格比如项目中引用了第三方的页面或有跳转第三方应用的地方必须保证同一账号能够登录第三方即单点登录或保证第三方页面或应用没有二次登录的地方。 微信登录 对微信登录审核要求较高。苹果要求如果项目中引用了微信登录那么同时要保证提供苹果登录功能但还有一个矛盾点是如果使用微信登录需要手机上有微信否则就无法登录这种情况下苹果的审核人员是不会审核通过的因为苹果审核人员的手机上没有微信。目前解决方式是监测手机上是否安装了微信如果没有安装微信则不暴露微信登录功能相应的如果应用中有跳转微信小程序的相关入口也要隐藏。 闪屏页面制作 苹果应用的闪屏页面是一个storyboard文件不能仅仅是一张图片需要按照格式要求制作。这里需要用到xcode工具也就是说只能在苹果电脑上制作该文件。详细过程如下 Uniapp ios制作自定义启动图storyboard文件_caijiangnan1121的博客-CSDN博客 重点 保证应用的服务器能被境外访问到有些国内的项目如政府项目对安全要求比较高服务器禁止境外访问这样的话苹果应用被审核的时候测试人员是无法访问的一定会被退回。 五、开发过程中的坑及解决方案 1. 消息推送uni-push2 向App应用推送消息通知需要用到第三方推送服务uniapp集成了个推服务不需要额外引入即可使用消息推送功能。  消息推送分为在线推送和离线推送。在线推送即App应用处于打开状态或在后台运行时进行的消息推送该部分功能通过uni-push内部即可实现。而离线推送需要在uni-push管理端进行厂商配置配置成功后会由手机厂商推送到用户手机。 App端实现消息推送的过程和思路 uni-push配置过程见官网uni-push2统一推送 | uni-app官网 注意苹果推送配置需要在苹果开发者平台申请专门的推送证书推送证书不是开发证书也不是发布证书就是推送证书。 消息推送其实是通过第三方服务将服务端信息推送给移动设备关键点是推送时需要明确目标设备是什么也就是说需要获取客户端的设备识别码。 ①绑定用户设备与用户Id uniapp提供了获取设备推送标识的api——uni.getPushClientId函数这样我们就拿到了设备的识别码但是仅仅有这样一个识别码是不够的有这个识别码仅仅能做到后端服务将消息推送到这个设备上但无法区分每个设备对应的用户是谁比如推送新闻是不需要用户是谁的但如果推送业务消息比如银行的余额变更就需要这个设备的用户是谁因此在获取到设备识别码之后还要将用户Id和设备信息绑定在一起。unipush提供了一个将设备编码绑定别名的函数这个别名可以是我们的用户Id。 绑定别名的云函数示例云函数创建过程可参考官网 函数文件名uniBindAlias/index.js(文件名可根据业务自定义) use strict; const uniPush uniCloud.getPushManager({appId: xxxx }) //注意这里需要传入你的应用appId exports.main async (event, context) {return await uniPush.cidBindAlias([{cid: event.push_clientid, // 设备推送编码alias: event.userId // 用户Id}]) }; 云函数调用 在vue文件中可以直接调用云函数调用示例如下 uniCloud.callFunction({name: uniBindAlias,data: {push_clientid: this.push_clientid,userId: this.userId}}) 其中name的值是被调用的云函数文件名。 ②推送消息 推送云函数示例如下 云函数文件名uniPush/index.js use strict; const uniPush uniCloud.getPushManager({appId: xxxxxx //app的id }) exports.main async (event, context) {let obj JSON.parse(event.body) // obj是后端传入的参数let data {title: obj.title,content: obj.content,payload: obj.data,force_notification: true,channel: { // 华为消息通道HW: LOW // 默认一天推送两条消息公共消息},options: { // 小米、oppo、vivo的消息通道各自有默认条数限制都是公共消息XM: { /extra.channel_id: xxxx},OP: {/channel_id: xxxxx},VV: {/classification: 0}}}if (obj.hasOwnProperty(alias)) { // 接收后端发送的目标设备别名let alia obj.alias;if (alia instanceof Array alia.length 0) {data.getui_alias obj.alias;}if (typeof(alia) string alia.length 0) {data.getui_alias obj.alias;}}if (obj.hasOwnProperty(type)) {let type obj.type;if (type ! 1) { //私信消息,不限条数data.channel.HW NORMAL; //华为私信通道设置为NORMALlet options {HW: {/message/android/notification/importance: NORMAL,/message/android/category: WORK},XM: {/extra.channel_id: xxx},OP: {/channel_id: xxxx},VV: {/classification: 1}}data.options options}}return await uniPush.sendMessage(data)}; 推送消息是由后端发起的当云函数上传到云空间后在云空间上查看这个云函数会有一个链接地址后端调用这个地址即相当于调用云函数了。  ③解绑 如果同一台手机登录多个账号那么最好将之前的账号和设备解绑然后再将新账号和设备绑定。 解绑函数示例云函数文件名uniUnBindAlias/index.js use strict; const uniPush uniCloud.getPushManager({appId: _xxxxxx }) //注意这里需要传入你的应用appId exports.main async (event, context) {return await uniPush.unboundAlias([{cid: event.push_clientid,alias: event.userId}]) }; vue文件中调用解绑云函数示例 uniCloud.callFunction({name: uniUnBindAlias,data: {push_clientid: _this.push_clientid,userId: this.userId}}) ④移动端通知弹窗 在App.vue的onLaunch中 uni.onPushMessage((res) {console.log(收到推送消息, res); //监听推送消息if (res.type click) {let time new Date().getTime();uni.navigateTo({url: //跳转到对应的通知页面});} else if (res.type receive) {//如果发送通知的参数force_notification不是true此时res.type的值是receive需要手动创建一个本地通知当点击这个通知的时候会再次触发onPushMessage这个事件而此时res.type的值就会变成clickuni.createPushMessage({payload: res.data.payload,content: res.data.content,title: res.data.title});} else {}}); 2. 微信审核 如果项目中要求有微信登录、微信支付、打开微信小程序等功能就需要到微信开发者平台注册账号、添加应用。只要按要求提供资料即可。唯一比较麻烦的是应用开发主体需要有官方网站官网上要有该App应用的名字及App相关介绍并且该网站要进行备案否则微信不予审核通过。 3. 全屏遮罩 在开发中经常会用到弹窗效果一般是背景黑色半透明遮住全屏。但是在uniapp项目中普通的写法是不能达到这个效果的在vue文件中写弹窗效果不能遮挡住原生导航和底部菜单只能遮住中间部分显然不是我们想要的效果针对这个问题uniapp提供了nvue的解决方案。 以最简单的退出登录功能为例正常的操作流程是在某个页面中点击退出按钮然后会弹出退出确认框确认框的背景应该是全屏半透明代码示例如下 ①首先要在退出按钮所在文件(pages/my/my.vue)的同级目录下创建一个subNvue文件夹pages/my/subNvue然后在该文件夹内新建Logout.nvue文件注意是nvue文件。 ②然后在pages.json文件中增加配置即在path值为“pages/my/my”的对象下的style下的app-plus下增加subNvues配置项代码示例如下 {path: pages/my/my,style: {navigationStyle: custom,enablePullDownRefresh: false,app-plus: {subNVues: [{id: popupLogout, // 唯一标识path: pages/my/subNvue/Logout, // 页面路径type: popup, // 类型为弹窗style: {margin: auto,width: 750upx,height: 1334upx,color: #3476FE,background: transparent}}]}}} ③在退出按钮所在文件my.vue中增加对弹窗nvue文件的初始化 initLogoutSubNvue() {let _this this;this.logoutSubNVue uni.getSubNVueById(popupLogout); //popupLogout是在pages.json中注册的subNvue的iduni.$on(popup-logout-message, (data) { // popup-logout-message 是Logout.nvue中向外抛出的信息在本页面中通过uni.$on监听从参数data中可以取到值。if (data.isClose) {_this.logoutSubNVue.hide(fade-out, 300);}if (data.isConfirm) {_this.logoutSubNVue.hide(fade-out, 300);_this.doLogout();}});}, uni.$on方法用于接收subnvue文件向外层传递的参数通过data来接收参数。  ④nvue文件部分代码 templateview classpopup-logout-page click.stopview classlogout-wrapperview classpopup-headertext classtitle确定退出登录吗?/text/viewview classpopup-bottomview classbtn left-btn clickdebounce(onClose)()text classtext点错了/text/viewview classbtn right-btn clickdebounce(onConfirm)()text classtext确定/text/view/view/view/view /template methods: {onClose() {uni.$emit(popup-logout-message, {isClose: true});},onConfirm() {uni.$emit(popup-logout-message, {isConfirm: true});}} uni.$emit方法用于向外部发送事件参数外层通过uni.$on来接收对应的事件参数。 注意 .nvue文件中的像素单位要使用upx。此外在.nvue文件中写代码时会发现缓存问题非常严重现象就是写完代码在模拟器或者手机上样式不更新。这时需要重启Hbuilder重启模拟器再看开发效果。 4. 状态栏高度 如果使用uniapp自带的导航栏是不需要设置状态栏的但有些情况下我们需要修改导航栏的样式或者在导航栏上设置多个功能按钮这样就需要自定义导航栏。自定义导航栏就需要额外设置状态栏。 设置状态栏高度代码如下 view :style{ height: statusBarHeight px }/view created() {//获取手机状态栏高度this.statusBarHeight uni.getSystemInfoSync()[statusBarHeight];}, 注意如果在app内打开webview并且webview内的页面自带导航头那么需要将设备的状态栏高度传递给webview保证webview内页的状态栏高度显示正常传递方式见后面webview功能介绍。 5. 应用更新 app应用的更新分为整包更新和wgt包更新。整包更新即重新下载安装应用wgt包更新相当于补漏洞不需要重新下载安装包仅更新部分内容例如王者荣耀的小版本更新就属于wgt包更新。但wgt包的更新有一定限制不是所有的功能变更都能通过wgt包更新完成详情见官网。 这里要介绍一下app更新的实现逻辑和整包更新的方法。 实现逻辑 ①app端获取本机应用版本号和服务器端做对比如果低于服务器端则弹出更新提示部分代码如下 获取本机应用版本号 this.versionName uni.getAppBaseInfo().appVersion 版本号对比函数v1是服务器返回版本号v2是本机应用版本号 compare(v1 0, v2 0) {console.log(v1,v2);v1 String(v1).split(.)v2 String(v2).split(.)const minVersionLens Math.min(v1.length, v2.length);let result 0;for (let i 0; i minVersionLens; i) {const curV1 Number(v1[i])const curV2 Number(v2[i])if (curV1 curV2) {result 1break;} else if (curV1 curV2) {result -1break;}}if (result 0 (v1.length ! v2.length)) {const v1BiggerThenv2 v1.length v2.length;const maxLensVersion v1BiggerThenv2 ? v1 : v2;for (let i minVersionLens; i maxLensVersion.length; i) {const curVersion Number(maxLensVersion[i])if (curVersion 0) {v1BiggerThenv2 ? result 1 : result -1break;}}}return result;}, 下面代码判断应用版本号和服务器端版本号如果服务器版本号大于本地版本号则显示更新弹窗 if (this.compare(this.updateVersion, this.versionName) 0) {uni.$emit(send-version-message, { //将服务器版本传递给更新窗口subNvue在更新窗口中接收versionInfo信息versionInfo: this.updateVersion});this.checkSubNVue.show(fade-in, 300, function() { //显示更新弹窗该弹窗在本页面onShow时初始化this.checkSubNVue uni.getSubNVueById(settingCheckUpdate);});}else {uni.showToast({title: 当前已是最新版本~,icon: none,mask: true,duration: 2000});return;} ②更新应用并安装 安卓应用和苹果应用的更新方式不同安卓应用可以直接从服务器端下载安装包而苹果应用一定要跳转的苹果应用市场才能更新下载。 核心代码如下 if (this.platform android) {const downloadTask uni.downloadFile({url: https://www.xxxx.cn/应用名.apk,//服务器端apk包地址success: (downloadResult) {if (downloadResult.statusCode 200) {plus.runtime.install(downloadResult.tempFilePath,{force: false},function () {console.log(install success...);_this.onClose();},function (e) {console.error(install fail...);});}},fail: (res) {},complete: () {downloadTask.offProgressUpdate(); //取消监听加载进度}});downloadTask.onProgressUpdate((res) { //监听下载进度同时显示在界面上。this.percent res.progress;this.download Number(res.totalBytesWritten / 1024 / 1024).toFixed(2);this.total Number(res.totalBytesExpectedToWrite / 1024 / 1024).toFixed(2);console.log(已经下载的数据长度 res.totalBytesWritten);console.log(预期需要下载的数据总长度 res.totalBytesExpectedToWrite);});} else {plus.runtime.launchApplication({action: itms-apps://itunes.apple.com/cn/app/id${this.versionInfo.appleId} //打开苹果应用市场this.versionInfo.appleId的值就是应用的苹果市场上的id上架应用后在苹果开发平台能看到},function (e) {console.log(Open system default browser failed: e.message);});} 备注 uniapp本身提供了一套应用更新的体系但是需要走流量、收费对于预算充足的项目来说可以直接使用uniapp提供的功能省时省力安全可靠而对于没有预算的穷酸项目只能自行开发。 6. 清除缓存 一般的app应用都需要具备清除缓存功能否则会导致应用体积越来越大占用手机空间。清除缓存需要两步 ①获取缓存大小 formatSize() {let that this;plus.cache.calculate(function (size) {let sizeCache parseInt(size);if (sizeCache 0) {that.fileSizeString 0B;} else if (sizeCache 1024) {that.fileSizeString sizeCache B;} else if (sizeCache 1048576) {that.fileSizeString (sizeCache / 1024).toFixed(2) KB;} else if (sizeCache 1073741824) {that.fileSizeString (sizeCache / 1048576).toFixed(2) MB;} else {that.fileSizeString (sizeCache / 1073741824).toFixed(2) GB;}});}, ②清除缓存 onClearCache() {uni.showLoading({title: 缓存清理中...});let that this;let os plus.os.name;if (os Android) {let main plus.android.runtimeMainActivity();let sdRoot main.getCacheDir();let files plus.android.invoke(sdRoot, listFiles);let len files.length;if (len 0) {uni.hideLoading();}for (let i 0; i len; i) {let filePath files[i]; // 没有找到合适的方法获取路径这样写可以转成文件路径plus.io.resolveLocalFileSystemURL(filePath,function (entry) {if (entry.isDirectory) {entry.removeRecursively(function (entry) {uni.hideLoading();//递归删除其下的所有文件及子目录uni.showToast({title: 缓存清理完成,duration: 2000});that.formatSize(); // 重新计算缓存setTimeout(function () {uni.navigateBack();}, 2000);},function (e) {uni.hideLoading();uni.showToast({icon: none,title: e.message,duration: 2000});});} else {uni.hideLoading();entry.remove();}},function (e) {uni.hideLoading();uni.showToast({icon: none,title: 文件路径读取失败,duration: 2000});});}} else {plus.cache.clear(function () { //一次清理不干净需要清理两次plus.cache.clear(function () {uni.hideLoading();uni.showToast({title: 缓存清理完成,duration: 2000});that.formatSize();});});}} 7. webview uniapp中提供webview组件通过此组件可以在app内打开外部网页。使用webview嵌套在app内可以降低app的开发成本和更新效率。app更新需要上架应用市场等待审核但是如果使用webviewwebview中的内容只需要自行在服务器端更新发布即可无需上架应用市场审核对于紧急bug修改、应用快速更新有很大的帮助。 webview使用示例 web-view :srcurl messageonReceiveData/web-view 变量url是要打开的网页地址传递给目标网页的参数只能放在url中 onReceiveData是从webview内的网页接收数据的函数。 url传参示例 uni.getSystemInfo({success: (sysinfo) {statusbar sysinfo.statusBarHeight; //当前设备状态栏高度_this.url _this.url statusbar statusbar;}}); 为保证每次打开webview中的内容都是最新的在url中还需要传入时间戳:  this.url https://www.xxxxx.com/?time939848933434/#/你的路由; 说明目前只有通过web-view组件的写法才能从外部网页获取参数其它webview的实现方式无法获取外部网页传递进来的参数。 外部网页向webview传递参数代码示例 uni.postMessage({data: {type: miniProgram,url: gh_56b2c43416a4}}); data中的参数就是要传递给app的参数在app中通过之前的onReceiveData方法接收参数 onReceiveData(event) {console.log(event.detail.data[0].type); // miniProgram } 8. 分享 核心代码 onShare(type) {let _this this;if (type weixin) { //分享到微信uni.share({provider: weixin,scene: WXSceneSession,type: 0,href: _this.shareUrl, //分享的url地址title: 欢迎来到 xxx APP,imageUrl: https://xxxxx/logo.png, //分享时显示的图片缩略图summary: 我正在使用 xxx APP快来加入吧,success: function (res) {console.log(success: JSON.stringify(res));},fail: function (err) {uni.showToast({title: JSON.stringify(err),icon: none,mask: true,duration: 3000});}});} else if (type friend) {//分享到朋友圈uni.share({provider: weixin,scene: WXSceneTimeline,type: 0,href: _this.shareUrl,title: 欢迎来到 xxx APP,summary: 我正在使用 xxx APP快来加入吧,imageUrl: https://xxxx/logo.png,success: function (res) {console.log(success: JSON.stringify(res));},fail: function (err) {uni.showToast({title: JSON.stringify(err),icon: none,mask: true,duration: 3000});}});} else if (type link) { // 复制到剪贴板uni.setClipboardData({data: _this.shareUrl,success: () {uni.showToast({title: 已复制到剪贴板,icon: none,mask: true,duration: 3000});}});}} 9. 地图 在h5中打开高德、百度地图的方法 openMapApp(type) {/* Start 判断手机是IOS还是安卓 */let u navigator.userAgent;//判断是否安卓let isAndroid u.indexOf(Android) -1 || u.indexOf(Linux) -1;// 判断是否IOSlet isIOS !!u.match(/\(i[^;];( U;)? CPU.Mac OS X/);/* End */if (type gaode) {//高德地图if (isAndroid) {window.location.href androidamap://poi?sourceApplicationsoftnamekeywords${this.location}dev0; //location是要导航的位置是汉字} else if (isIOS) {window.location.href iosamap://poi?sourceApplicationapplicationNamename${this.location}dev0;}} else if (type baidu) {//百度地图if (isAndroid) {window.location.href bdapp://map/place/search?query${this.location}srcandr.baidu.openAPIdemo;} else if (isIOS) {window.location.href baidumap://map/place/search?query${this.location}srcios.baidu.openAPIdemo;}}}, 10. 访问量统计 uniapp提供了一套完整的访问量统计服务同样是付费使用有钱的项目可以直接拿来用没钱的请继续阅读。 参考uniapp官方的访问量统计功能的统计维度可以从手机品牌、型号、日活、月活、装机量等维度来设计功能。 统计访问量的一个关键点是要知道访问终端的唯一识别码如果一个app需要登录才能使用那么可以把登录账号做为该终端唯一识别码如果app不需要登录也能使用那么就需要通过获取手机设备的标识做为唯一识别码代码示例如下 let deviceBrands [huawei, xiaomi, oppo, vivo, lenovo];//主流安卓手机onBehavior() {let _this this;const deviceBrand uni.getSystemInfoSync().deviceBrand; //获取设备品牌const deviceModel uni.getSystemInfoSync().deviceModel; //获取设备型号if (uni.getSystemInfoSync().platform ios) {console.log(ios系统);//ios系统plus.device.getInfo({success: function (e) {console.log(getDeviceInfo success: e.uuid);let paras { deviceBrand, deviceType: deviceModel, deviceCode: e.uuid };_this.callTongji(paras);//调用后端的统计接口发送相关参数},fail: function (e) {console.log(getDeviceInfo failed: JSON.stringify(e));}});} else {//android系统// let deviceBrand uni.getSystemInfoSync().deviceBrand;if (deviceBrands.includes(deviceBrand)) {//主流机型let OAID uni.getSystemInfoSync().oaid;console.log(getOAID success: OAID);if(OAID) {let paras { deviceBrand, deviceType: deviceModel, deviceCode: OAID };_this.callTongji(paras);}} else {//非主流机型plus.device.getInfo({success: function (e) {console.log(getDeviceInfo success: e.uuid);let paras { deviceBrand, deviceType: deviceModel, deviceCode: e.uuid };_this.callTongji(paras);},fail: function (e) {console.log(getDeviceInfo failed: JSON.stringify(e));}});}}}, 说明苹果设备和非主流安卓手机通过plus.device.getInfo获取uuid做为唯一标识主流安卓手机华为、小米、OPPO、VIVO、lenovo通过uni.getSystemInfoSync().oaid获取oaid做为唯一标识。 小米市场审核的坑 uniapp提供了获取手机oaid的方法plus.device.getOAID但是该方法在小米低版本系统中会引发获取手机电话管理权限的弹窗导致审核不过所以需要使用uni.getSystemInfoSync().oaid替代。 11. 隐私政策 只有安卓应用市场对隐私政策有要求至少三个地方需要有隐私政策 ①进入App应用之前需要用户先阅读并同意隐私政策然后才能进入到应用内。uniapp提供了解决方案详见uni-app官网 ②需要提供一个可访问的隐私政策地址用于应用市场审核。 ③需要在应用内有一个明显的可以随时阅读隐私政策的地方。 隐私政策内容 ①要明确引入了哪些sdk每个sdk都获取了用户的哪些权限 核心内容示例 一我们可能向您收集的个人信息 个人信息是指以电子或者其他方式记录的能够单独或者与其他信息结合识别特定自然人身份或者反映特定自然人活动情况的各种信息。本隐私政策下您必须授权我们收集和使用您的个人信息包括 1个人基本信息 手机验证码进行认证 2定位信息 进行附近商户推荐和查询 3设备信息 我们的产品基于DCloud uni-app(5 App/Wap2App)开发应用运行期间需要收集您的设备唯一识别码IMEI/android ID/DEVICE_ID/IDFA、SIM 卡 IMSI 信息、OAID以提供统计分析服务并通过应用启动数据及异常错误日志分析改进性能和用户体验为用户提供更好的服务。详情内容请访问 《DCloud用户服务条款》 消息推送服务供应商由每日互动股份有限公司提供推送技术服务我们可能会将您的设备平台、设备厂商、设备品牌、设备识别码等设备信息应用列表信息、网络信息以及位置相关信息提供给每日互动股份有限公司用于为您提供消息推送技术服务。我们在向您推送消息时我们可能会授权每日互动股份有限公司进行链路调节相互促活被关闭的SDK推送进程保障您可以及时接收到我们向您推送的消息。详细内容请访问 《个推用户隐私政策》  我们涉及用户信息使用的SDK相关情况 一UniPush模块集成第三方SDK说明 SDK名称个推·消息推送 包名信息com.igexin、com.heytap、com.vivo.push、com.xiaomi.push 使用目的UniPush消息推送 涉及个人信息存储的个人文件、设备信息IMEI、MAC、ANDROID_ID、DEVICE_ID、IMSI、应用已安装列表、网络信息 个推隐私协议地址 个推用户隐私政策-个推文档中心 ②隐私政策的发布主体要与app应用的发布主体一致  12. Universal Links Universal Links的效果是在浏览器中输入ulink链接地址如果手机内安装了该应用则浏览器上方会自动出现打开xxx应用的提示按钮仅在iphone上有效。 uniapp提供了一套生成Universal Links的方案但是收费不差钱的可以直接用差钱的继续阅读。 设置Universal Links操作流程 这篇文章写的不错可参考Uniapp IOS universal link 配置流程_ios ulink-CSDN博客 注意生产环境服务器一定要可以被境外访问否则苹果检测不到服务器上的apple-app-site-association文件导致此功能不生效。 在微信开放平台有配置Universal Links的地方仅IOS应用需要配置因为传统的通过schemeUrl的方式打开app在微信中是不好用的只有通过Universal Links打开在微信中才可用。仅IOS可用。如果手机中没有安装app则会直接打开Universal Links对应地址的网页。 那么问题来了如果安卓系统想在微信中打开app应用有什么办法答案是不能直接在微信中打开app只能提示用户在浏览器中打开本页面然后通过schemeUrl的方式打开app。 典型案例是比如有人通过微信分享给你一个盒马上商品的链接打开页面后顶部会有一个立即打开的按钮如果是苹果系统点击按钮后就会直接打开盒马app如果是安卓系统则会打开一个新页面在新页面提示用户在浏览器中打开。 13. 模拟器 本人使用夜神模拟器模拟器下载及使用可自行百度。这里着重说明的是使用模拟器会比较卡有时缓存比较严重建议使用真机开发。 14. 通过外部链接打开App并跳转到目标页面 首先判断是否在微信环境中判断代码如下 is_weixin() {let ua window.navigator.userAgent.toLowerCase();if (ua.match(/MicroMessenger/i) micromessenger) {console.log(微信浏览器);return true;} else {console.log(不是微信浏览器);return false;}} 如果是在微信环境中跳转链接前要提示用户在浏览器中打开。 在h5页面中可以通过schemeUrl的方式打开app应用同时可以传递参数这样在app中可以通过获取参数进而打开指定的页面。 打开app示例 window.location xxx://pageuser/detail?id this.id //xxx是app的scheme的值//后面的是传递给app的参数。 在app中接收参数关键代码 plus.runtime.arguments //此段代码可以获取到url链接跳转到app的完整地址然后根据需要从中获取关键参数。 一般外部链接打开app应用然后在应用首页判断需要进入到哪个具体的目标页面为避免从目标页面回到首页后再次自动跳转目标页需要在首页进行判断如果第一次已经成功进入目标页那么就要给plus.runtime.arguments赋空值 plus.runtime.arguments null; plus.runtime.arguments ; 15.网络状态监测 app如果出现网络异常要给用户明显的提示或显示专门的无网络连接页面。此外苹果手机首次打开app应用时会获取网络权限在这个过程中app应用是无法连网的就需要通过app判断连网状态给出对应的提示内容。 uniapp提供了两种获取网络连接状态的方法 uni.getNetworkType可以主动判断当前是否连网uni.onNetworkStatusChange用来进行网络连接状态监听不同的方法可以用于不同的情景判断。 16.路由拦截 let list [navigateTo, redirectTo, reLaunch, switchTab];list.forEach((item) {uni.addInterceptor(item, {invoke(e) { //在这里面进行相关逻辑的编写。参数e中包含了路由信息。console.log(e, e);return e;},fail(err) {console.log(err, err);}});}); 17.请求封装与拦截 import {url } from /common/constant.js const request (config) {// 拼接完整的接口路径// config.url /api config.url;config.url url /api config.url;//判断是都携带参数if (!config.data) {config.data {};}let promise new Promise(function(resolve, reject) {uni.request({method: config.method || GET,url: config.url,data: config.data || {},timeout: 6000,header: config.header || {content-type: application/json,Authorization: Bearer uni.getStorageSync(token), //请求头添加tokenuni.getStorageSync(token)的数据是登录时存放在本地存储中的token数据},}).then(responses {// 异常if (responses.statusCode ! 200) {console.log(请求bug, config.url, responses);if (responses.data?.msg) {uni.showToast({title: responses.data.msg,icon: none,mask: true,duration: 3000});}reject({message: responses.data.msg});} else {let response responses.data; // 如果返回的结果是data.data的嫌麻烦可以用这个return res,这样只返回一个dataresolve(response);}}).catch(error {reject(error);})})return promise; }; uni.addInterceptor(request, {invoke(args) { //在args参数中可以设置request中的各项参数例如下面代码可以设置token信息// console.log(args,args);try {args.header[adq-token] uni.getStorageSync(token);} catch (e) {console.log(err, e);}} }) 18.UrlSchemes UrlSchemes可以在manifest.json进行配置安卓和苹果需要分别配置。UrlSchemes主要是用于第三方app打开本app或者通过外部链接地址打开本app。具体可参考官方文档 uni-app官网 总结 以上是通过uniapp开发app应用的关键点解释说明后续再遇到新问题会持续更新。
http://www.dnsts.com.cn/news/164833.html

相关文章:

  • 提供手机网站制作公司徐州市城乡建设局网站
  • 个人网站 备案护肤品网站建设策划书
  • 上海住房建设部官方网站网站建设完毕后怎么加后台
  • 手机网站建设服务商公司网站域名到期了去哪里缴费
  • 深圳高端网站定制设计七宝做网站公司
  • wordpress 手机 自建站东莞网站设计与制作公司
  • 简述网站规划的流程智能手机软件开发培训
  • 模板网站与定制网站的区别陵水专业网站建设
  • 电子商务与网站建设实践论文网站常见结构有那些
  • 网站建设主结构通过域名打开网站是做映射么
  • 西安网站外包做网站的尺寸1920
  • 邯郸模板建站教程什么网站可以做ui兼职
  • 网站建设要程序员吗建设网站只能是公司
  • 网站地图做计划任务建设厅特种作业
  • 如何免费开自己的网站seo计费系统源码
  • 做哈尔滨本地门户网站赚钱吗百度人工服务24小时
  • 昆山网站制作wordpress 机械模板下载
  • 制作html5网站一个新的app如何推广
  • 有免费的网站域名吗wordpress 公司主题
  • 怎么建设一个自己的网站首页江阴做网站哪家好
  • 门户网站开发设计方案wordpress joomla 菜单
  • 电子商务网站建设原则加强心理咨询网站的建设
  • 网站怎么搭建地产网站建设案例
  • 大型网站建设兴田德润专业阿里云wordpress在哪里设置
  • 德州万企互联网站制作今天的新闻大事
  • 什么网站推广比较好手机号注册网站
  • 网站建设平台计划书做网站的销售团队
  • 邵阳网站制作建设南宁门户网站
  • 青海建设厅网站尚少岩东莞宣传册设计
  • 商务网站制作公司wordpress建两个网站吗