前言
这里用的是uni-app自带的UniPush1.0(个推服务),所以只针对UniPush1.0介绍实现步骤。
建议查阅的文章:
当然现在已经出了UniPush2.0(HBuilderX 3.5.1及其以上版本支持),新项目的话还是推荐使用UniPush2.0。
如果要使用UniPush2.0,请移步 UniPush 2.0 使用指南 。
效果预览
前五张图片是Android(HUAWEI P30 Pro)真机效果,后面三张是Ios(iPhone XS Max)真机效果。
概述
产品介绍
UniPush是DCloud联合个推公司推出的集成型统一推送服务,内建了苹果、华为、小米、OPPO、VIVO、魅族、谷歌 FCM 等手机厂商的系统级推送和个推等第三方推送。
国内Android的Push是一个混乱的世界,因为Google的Push服务FCM 被墙(从HBuilderX2.7.10开始,支持谷歌FCM,参考: UniPush支持谷歌推送FCM配置指南),所以一些国内的安卓手机厂商各自做了自己的推送,比如华为、小米、OPPO、VIVO、魅族等,但还有很多国产手机厂商没有提供官方推送方案。三方独立公司如个推,则提供了独立的 push 方案。
在没有UniPush以前,如果只使用三方push,会在很多国产手机上因为节电设置而无法保活push进程,导致无法推送。
而如果每个安卓手机的官方Push SDK都集成开发一遍,这么多平台,工作量会非常巨大,管理维护也很麻烦。
UniPush解决了这个难题,开发者只需要开发一次。系统会自动在不同手机上选择最可靠的推送通道发送push消息,保障送达率。
UniPush即降低了开发成本、又提高了push送达率,并且免费,是当前推送的最佳解决方案。
技术架构
名词解释
名词 |
解释 |
通知消息 |
指定通知标题和内容后,由个推SDK自动处理在系统通知栏中展示通知栏消息,同时响铃或震动提醒用户(响铃和震动受手机系统的设置状态影响)。 |
透传消息 |
即自定义消息,消息体格式客户可以自己定义,如纯文本、json 串等。透传消息个推只传递数据,不做任何处理,客户端接收到透传消息后需要自己去做后续动作处理,如通知栏展示、弹框等。 |
ClientId |
个推业务层中的对外用户标识,用于标识客户端身份,由第三方客户端获取并保存到第三方服务端,是个推 SDK 的唯一识别号,简称 CID。 |
在线推送 |
app 在前台打开运行时,通过个推渠道下发消息。 |
离线推送 |
app在后台、锁屏、进程关闭时,通过厂商渠道下发消息。若未集成 android 多厂商、未配置 ios 推送证书,则该机型无法使用离线推送。 |
更多名词解释参考:个推名词解释 。
消息推送流程
开通 UniPush 推送服务
UniPush内部封装好了个推及主流厂商 SDK,在使用前必须开通相关服务:点此查看如何开通UniPush推送服务。
打开 DCloud开发者中心,登录后会进入我的应用列表。在左侧菜单点击uniPush,然后选择 1.0 或 2.0,进入Uni Push信息页,左上角显示为当前要操作的应用,点击可以切换应用。如下图所示:
用户首次使用UniPush功能时,需要向个推同步身份信息。已通过实名认证的用户,会直接将实名认证信息同步给个推。如下图所示:
未提交实名认证信息的用户,需要在页面中输入相关信息后提交,如下图所示:
应用开通UniPush功能时,需要提交应用相关信息,如下图所示:
注意:UniPush在申请开通时,需要确保输入的Android包名或iOS Bundle ID必须与打包时配置的一致,否则可能会导致无法收到推送消息。
Android平台:
Android包名必须与HBuilderX中App云端打包时配置的Android包名一致;Android应用签名必须填入打包时使用证书的SHA1指纹。
iOS平台:
iOS BundleId必须与HBuilderX中App云端打包时配置的Bundle ID(AppID)一致。
如果已经开通UniPush,会看到如下页面:
若需要支持主流Android厂商客户端接收离线推送,您需要完成 :Android 多厂商配置 。
iOS 平台还需要在 【配置管理】-【应用配置】页面上传推送证书,如何获取推送证书请参考个推官方文档教程:iOS证书配置指南。
核心代码
unipush.js
import phoneInfo from '@/common/js/phone-info.js'; import store from '@/store' let timer = null; let numloop = 0; import { pushEscalation } from "@/api/client-notice.js"
const uniPushObj = { cid: "", AppID: "你的AppID", AppKey: "你的AppKey", AppSecret: "你的AppSecret", MasterSecret: "你的MasterSecret", }
export default { getInfo() { uni.getSystemInfo({ success: res => { phoneInfo.systemInfo = res; } }); }, pushListener() { const token = uni.getStorageSync("token") || store.state.token; const platform = phoneInfo.systemInfo.platform.toLowerCase(); plus.push.addEventListener('click', res => { if (token) { if (platform == 'android') { const msg_type = res.payload.msg_type if (msg_type == 0) { console.log('安卓------在线'); } else { console.log('安卓------离线'); } } else { if (res.aps == null) { console.log('苹果------在线'); } else { console.log('苹果------离线'); } } } else { uni.redirectTo({ url: `pages/Login-Reg/Login/email-login` }) } }); plus.push.addEventListener('receive', res => { const messageTitle = res.title; const messageContent = res.content; if (platform == 'android') {
plus.push.createMessage(messageContent, res.payload, { title: messageTitle }); } else { const type = res.type if (res.aps == null && type == "receive") { plus.push.createMessage(messageContent, res.payload, { title: messageTitle }); } } }); }, getClientInfoLoop() { plus.push.getClientInfoAsync(info => { if (!info || !info.clientid) { console.log("cid为空========================================="); let infoTimer = null; infoTimer = setInterval(function() { if (cid) { clearInterval(infoTimer); uni.showModal({ content: cid }) uni.setStorageSync('cid', cid); uniPushObj.cid = cid } }, 50); } else if (info && info.clientid) { let cid = info.clientid; uni.setStorageSync('cid', cid); uniPushObj.cid = cid } }, function(e) { console.log('Failed', JSON.stringify(e)); let pinf = plus.push.getClientInfo(); let cid = pinf.clientid; if (cid) { uni.setStorageSync('cid', cid); uniPushObj.cid = cid } }) },
passCid() { pushEscalation({ "appid": uniPushObj.AppID, "cid": uniPushObj.cid }).then(response => { if (response.Code == 0) { console.log('----------> cid 绑定别名成功', response); } }) }, }
|
phone-info.js
export default { systemInfo: {}, manifestInfo: "" || uni.getStorageSync("widgetInfo"), }
|
APP.vue
<script> import phoneInfo from '@/common/js/phone-info.js'; import uniPushListener from '@/common/js/unipush.js'; export default { onLaunch: function() { uniPushListener.getInfo(); plus.screen.lockOrientation('portrait-primary'); uni.setStorageSync('cancelUpdate', 'false'); if (Object.keys(uni.getStorageSync('widgetInfo')).length == 0) { plus.runtime.getProperty(plus.runtime.appid, widgetInfo => { phoneInfo.manifestInfo = widgetInfo; uni.setStorageSync('widgetInfo', widgetInfo); }); } uniPushListener.getClientInfoLoop(); plus.runtime.setBadgeNumber(0); uniPushListener.pushListener(); } }; </script>
|