测试手机:
Android(小米,华为),离线在线均成功。
IOS,离线在线均成功。
废话不多说,如果确认配置没问题,直接拉到第2点看爬坑记录:
1、首先要确认配置没问题,这是一个很关键的点,不然你会发现你怎么测都有问题。。。
创建项目我就不多说了,创建完项目之后,需要配置好开发者中心的推送,Dcloud开发者中心。
这里要么你打包的时候自动生成应用和对应的appid,要么先创建应用,再去项目的manifest.json中把appid和应用名称补上。
应用生成后,点击进入对应appid的应用:
打开unipush,配置好相关数据之后,记录数据,一般包名可以用反域名,具体命名规则网上很多,eg: net.csdn.blog
自建证书的话,可以用Android Studio(AS)一键生成,或者配置JRE环境,用keytool命令生成
生成命令:
keytool -genkey -alias testalias -keyalg RSA -keysize 2048 -validity 36500 -keystore test.keystore
.jks和.keystore都是可以的,
查看命令:
keytool -list -v -keystore test.keystore
勾选uniPush之后,打包自定义调试基座,记得先勾选再制作。
除此之外,推送的话需要用自定义基座才能接收到推送(因为推送是需要根据app自身的特定信息去推送的,具体的话可以看官网文档)
配置方面总结来说分3点:
A、配置开发者中心Dcloud的uniPush;
B、勾选uniPush模块;
C、配置证书制作自定义基座。
爬坑开始!爬坑开始!爬坑开始!
2、直接说超级大坑!!!!真机调试推送的时候是不会报错的!!!!F*ck(声嘶力竭!!!)
意思就是控制台根本不会告诉你有什么错,反正就是进程阻塞了。
重要!!!提醒一句,每次更新完代码保存之后,不要相信热更新!!!!直接手动操作手机清除后台,再重新打开APP
这两个坑是比较大的,根本就不知道哪里错了,天天在哪里改改改,一会可以一会不行,人直接疯了!!
---- 普通坑分割线 ----
普通坑指的是,推送对对格式要求比较严格,要完全对上才行,具体哪里可以改动,可以拿成功的推送格式再去慢慢尝试更改。
附推送格式:
【APP在线推送】【在线】【在线】
{
"payload": "payload内容",
"title": "【编号001】推送测试标题",
"content": "【编号001】推送测试内容3"
}
{
"payload": {
"path": "/pages/message/message",
"type": 0
},
"title": "【编号001】推送测试标题",
"content": "【编号001】推送测试内容"
}
在线推送走的是上半部分(如图):
【APP离线推送】【离线】【离线】
离线推送的难点在于intent的格式,其他都还好,就是payload的格式整个网上几乎都找不到,这里附上案例(终于爬出坑了):
intent:#Intent;action=android.intent.action.oppopush;launchFlags=0x14000000;component=填写你的包名;S.UP-OL-SU=true;S.title=填写标题3;S.content=填写内容3;S.payload=填写附加的payload;end
普通示例:
intent:#Intent;action=android.intent.action.oppopush;launchFlags=0x14000000;component=net.csdn.blog;S.UP-OL-SU=true;S.title=测试标题3;S.content=测试内容3;S.payload=附加内容;end
出坑示例: 出坑示例: 出坑示例(payload是JSON对象)
错误示例:
intent:#Intent;action=android.intent.action.oppopush;launchFlags=0x14000000;package=net.csdn.blog;component=net.csdn.blog/io.dcloud.PandoraEntry;S.UP-OL-SU=true;S.title=【编号001】推送测试标题;S.content=【编号001】推送测试内容;S.payload={"path":"/pages/message/message","type":0};end
正确示例:(payload需要把JSON对象先进行urlencode编码)编码编码编码编码编码编码
intent:#Intent;action=android.intent.action.oppopush;launchFlags=0x14000000;package=net.csdn.blog;component=net.csdn.blog/io.dcloud.PandoraEntry;S.UP-OL-SU=true;S.title=【编号001】推送测试标题;S.content=【编号001】推送测试内容;S.payload=%7B%22path%22%3A%22%2Fpages%2Fmessage%2Fmessage%22%2C%22type%22%3A0%7D;end
离线推送(自己根据文档配置好厂商推送,去申请key填写进unipush就好了)的时候,使用intent那部分,传过去后正常使用就行,app会自动解码,不需要再进行decode,不过获取到的是JSON格式,离线是JSON,在线是Object,这里要分开处理,不然要出错!!!然而,只会阻塞进程,不会报错!!!
附上简化版的业务代码:
// uniPush推送
// 透传是不会有消息提醒的,需要自己创建消息plus.push.createMessage
// #ifdef APP-PLUS
let client = uni.getSystemInfoSync().platform
plus.push.addEventListener("receive", function(msg) {
if (client == 'ios') { //如果是IOS
// ios相对比较少坑,APNs Apple Push Notification service,aps是ios自带的,自定义基座调试的时候可以看到,对比情况做判断就行了
//【APP在线】收到消息,不会触发系统消息,需要创建本地消息,但不能重复创建。必须加msg.type验证去除死循环,因为ios哪怕是自己船舰的本地消息,也会触发receive
if (msg.aps == null && msg.type == "receive") {
let payload = JSON.stringify(msg.payload);
let messageTitle = msg.title;
let messageContent = msg.content;
//创建本地消息
plus.push.createMessage(messageContent, payload, {
title: messageTitle
});
}
}
if (client == 'android') {
// 如果是Android,当APP在线时,收到透传消息不会进入系统消息,需要发送本地提醒。
//【APP在线】PS!!!!调试的时候跟app打开有关,有时候会进receive,也会执行createMessage,但是!!!不会打印输入任何东西!!!
//【APP在线】不会执行打印方法的话,关闭APP重新打开可能会收到,也可能还是会收不到!!!太坑了!!!实在不行重新编译!!再不行就只能洗洗手换手机再来测一下了。。。
//【APP在线】总而言之,测推送的时候,如果确实找不到问题,可以把app关掉,重新打开试一下,说不定就可以了,或者卸载重新编译
let payload = JSON.stringify(msg.payload);
let messageTitle = msg.title;
let messageContent = msg.content;
plus.push.createMessage(messageContent, payload, {
title: messageTitle
});
// 创建app角标,自己根据逻辑另写,就是天天看到的微信99+
plus.runtime.setBadgeNumber(98)
}
}, false);
// 判断点击推送跳转页面
plus.push.addEventListener("click", function(msg) {
/**
* [APP在线]:
* 使用的,{ "payload": { "pagePath": "/pages/message/message", "type": 0 }, "title": "xxx", "content": "xxx" }
* 关于receive事件,只有发送的是"透传数据 && 不是标准格式 && 当前应用在活动",这3个条件同时满足,才可以响应receive事件
* 此外,payload传过来的直接解析成对象。。我吐了。。
* [APP离线]:
* payload使用OBJECT的JSON格式进行urlencode编码!!!APP读取的时候会自动解析为JSON格式!!!
* 使用intent:#Intent;action=android.intent.action.oppopush;launchFlags=0x04000000;package=net.csdn.blog;component=net.csdn.blog/io.dcloud.PandoraEntry;S.UP-OL-SU=true;S.title=xxx;S.content=xxx;S.payload=%7B%22pagePath%22%3A%22%2Fpages%2Fmessage%2Fmessage%22%2C%22type%22%3A0%7D;end
*/
/**
* 如果点击没触发事件,有2种可能:
* 1、格式不正确,重新核对一下参数;
* 2、代码报错阻塞!!!但是报错不会显示出来!!!!!!我吐了!!!!!!!!!!!!!
*/
// 在线是object,不用解析,直接使用
// 离线是JSON,要parse成object才能使用
let payload = msg.payload
if (typeof payload != 'object') {
// 如果是字符串(JSON),则解析
payload = JSON.parse(payload)
}
// 业务逻辑
// balabala...
});
// #endif
关于前面的签名,unipush的开通和使用指南,这里直达官方文档:
最后:
文章写的乱七八糟的,本来想细说,发现挺多东西要配置的,所以就贴了上面3个官方链接。
因为时间不是很充足,所以写的有点乱,看到这里上面应该全忘了,直接总结几点:
1、离线推送的intent中的payload如果要传json的话,先进行urlencode编码;
2、离线推送接收到的是json格式,在线推送接受到的是object,两者相差一个parse解析,逻辑分开写;
3、需要使用自定义基座调试,格式要求严格;
4、如果出现错误,会阻塞进程,不会报错!!!或者,成功运行,不打印(请花样重启)!!!!