前言
这里用的是uni-app自带的UniPush1.0(个推服务),所以只针对UniPush1.0介绍实现步骤。
建议查阅的文章:
当然现在已经出了UniPush2.0(HBuilderX 3.5.1及其以上版本支持),新项目的话还是推荐使用UniPush2.0。
如果要使用UniPush2.0,请移步 UniPush 2.0 使用指南 。
效果预览
[{"url":"https://bu.dusays.com/2023/01/05/63b6852197bb4.jpg","alt":"图1"},{"url":"https://bu.dusays.com/2023/01/05/63b6852433cec.jpg","alt":"图2"},{"url":"https://bu.dusays.com/2023/01/05/63b68526c6658.jpg","alt":"图3"},{"url":"https://bu.dusays.com/2023/01/05/63b6852933c86.jpg","alt":"图4"},{"url":"https://bu.dusays.com/2023/01/05/63b6852c02154.jpg","alt":"图5"},{"url":"https://bu.dusays.com/2023/01/05/63b6852fdc555.jpg","alt":"图6"},{"url":"https://bu.dusays.com/2023/01/05/63b68532c8098.jpg","alt":"图7"},{"url":"https://bu.dusays.com/2023/01/05/63b68534edac1.jpg","alt":"图8"}]
前五张图片是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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
| 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
1 2 3 4
| export default { systemInfo: {}, manifestInfo: "" || uni.getStorageSync("widgetInfo"), }
|
APP.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <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>
|