背景
用uniapp开发个APP,但是不上架应用市场,需要实现消息推送,针对android和ios。
解决方案
核心结论
-
Android :完全没问题,所有推送通道基本都能用,只是厂商通道的到达率会受影响。
-
iOS :技术上可以实现,但分发方式决定了你能使用的推送环境。
第一部分:Android 推送(不上架市场)
Android 在这种情况下依然有很好的推送支持。
方案 1:继续使用 UniPush(个推)【推荐】
这是最省心的方案,可以继续使用我们之前讨论的 UniPush。
优势:
-
一套代码兼容 Android 和 iOS
-
无需自己维护长连接
-
官方有较好的通道管理
注意事项:
-
厂商通道(小米、华为等) :由于应用未上架对应的应用市场,厂商推送通道基本上无法使用或到达率极低。厂商通道要求应用必须在其商店上架或通过白名单审核。
-
主要依赖 :个推的自有通道 (在应用存活时有效)和辅助通道。
效果评估:
-
应用在前台或后台存活:推送到达率很高
-
应用被彻底杀死:推送可能无法接收(因为无法使用厂商的系统级通道)
方案 2:集成 FCM(Firebase Cloud Messaging)
如果你的用户主要在海外,或者想要更好的推送体验,可以考虑 FCM。
优势:
-
Google 官方推送,到达率很高
-
应用被杀后依然能收到推送
-
免费使用
劣势:
-
在国内基本不可用(被墙)
-
需要额外集成 Firebase SDK
-
与 UniPush 的 API 不统一
集成步骤:
-
在 Firebase Console 创建项目
-
配置 Android 应用,下载
google-services.json -
在 UniApp 中通过原生插件或 uni-push 的 FCM 通道集成
方案 3:自建长连接【不推荐】
技术上可行,但:
-
耗电量大
-
需要自己维护服务器和连接管理
-
不同手机厂商的后台策略需要单独适配
第二部分:iOS 推送(不上架 App Store)
iOS 的情况比较复杂,取决于你的分发方式:
分发方式与推送能力对照表
| 分发方式 | 推送证书类型 | 推送环境 | 设备数量限制 | 推送效果 | 备注 |
|---|---|---|---|---|---|
| App Store 上架 | Production | Production | 无限制 | ✅ 最佳 | 理想情况,但你不选择 |
| 企业签名 | Production | Production | 无限制 | ✅ 完全正常 | 最佳选择,但证书昂贵且难申请 |
| TestFlight | Production | Production | 10,000台 | ✅ 完全正常 | 需要先提交审核,90天有效期 |
| AdHoc 分发 | Production | Production | 100台 | ✅ 完全正常 | 适合小范围测试 |
| 开发证书 | Development | Sandbox | 100台 | ⚠️ 仅开发环境 | 仅用于真机调试 |
具体方案分析
方案 1:企业签名分发 + UniPush【推荐用于内部应用】
适用场景: 企业内部使用的应用,员工数量较多。
优势:
-
推送功能与上架应用完全一样
-
无设备数量限制
-
使用 Production 环境,推送稳定
要求:
-
需要申请 Apple Developer Enterprise Program(年费 $299)
-
企业账号申请难度较大,需要提供邓白氏编码和企业证明
-
严禁用于公开分发,否则会被苹果封号
配置步骤:
-
申请企业开发者账号
-
创建企业版描述文件
-
配置 Production 推送证书(与上架应用相同)
-
在 DCloud 后台上传 Production 推送证书
-
打包时选择企业证书签名
方案 2:AdHoc 分发 + UniPush【推荐用于测试/小范围】
适用场景: 测试版本、客户演示、小范围使用(≤ 100台设备)
优势:
-
使用 Production 推送环境
-
推送效果与正式版无异
-
成本低(使用个人或公司开发者账号即可)
限制:
-
最多 100 台设备,需要在苹果后台注册设备的 UDID
-
每增加设备需要重新打包
配置步骤:
-
在苹果开发者后台添加测试设备的 UDID
-
创建 AdHoc 描述文件
-
配置 Production 推送证书
-
打包时选择 AdHoc 描述文件
方案 3:TestFlight 分发【折中方案】
适用场景: 测试用户较多(最多1万人),且可以接受90天的有效期
优势:
-
支持最多 10,000 名外部测试员
-
使用 Production 推送环境
-
无需收集设备 UDID
限制:
-
需要先提交到 App Store Connect(但不一定要审核通过)
-
每个版本有效期 90 天
-
外部测试需要苹果审核(通常1-3天)
第三部分:具体操作建议
根据你的实际场景,我推荐以下方案:
场景 A:企业内部应用
-
Android:UniPush(个推自有通道)
-
iOS:企业签名 + UniPush
-
说明:这是功能最完整的方案,推送体验接近上架应用
场景 B:小范围测试/客户演示
-
Android:UniPush
-
iOS:AdHoc 分发 + UniPush(设备≤100)或 TestFlight(设备>100)
-
说明:成本最低,功能完整
场景 C:主要用户在国内的公开分发
-
Android:UniPush + 引导用户授权自启动、电池优化白名单
-
iOS :只能上架 App Store,否则无法合法公开分发
-
说明:iOS 没有合法的非上架公开分发方案
场景 D:主要用户在海外
-
Android:FCM + UniPush
-
iOS :必须上架 App Store
-
说明:海外环境 FCM 推送效果更好
第四部分:代码实现注意事项
无论选择哪种方案,前端代码基本不变:
javascript
// App.vue - 通用推送代码
export default {
onLaunch() {
this.initPush();
},
methods: {
initPush() {
// 监听推送消息
uni.onPushMessage((res) => {
console.log('收到推送:', res);
this.handlePushMessage(res);
});
// 获取CID
uni.getPushClientId({
success: (res) => {
console.log('Client ID:', res.cid);
this.sendCidToServer(res.cid);
}
});
},
handlePushMessage(pushData) {
// 处理推送消息
if (pushData.type === 'notification') {
// 通知栏消息
uni.showModal({
title: pushData.title,
content: pushData.content,
showCancel: false
});
} else if (pushData.payload) {
// 透传消息,包含自定义数据
try {
const payload = JSON.parse(pushData.payload);
if (payload.page) {
uni.navigateTo({
url: payload.page
});
}
} catch (e) {
console.error('解析推送数据失败:', e);
}
}
},
sendCidToServer(cid) {
// 将CID发送到你的业务服务器
uni.request({
url: 'https://your-server.com/api/save-cid',
method: 'POST',
data: {
cid: cid,
platform: uni.getSystemInfoSync().platform,
userId: '当前用户ID' // 如果有的话
}
});
}
}
}
Android 额外优化建议
对于不上架市场的 Android 应用,建议:
希望这个详细的分析能帮助你做出合适的技术选型!
-
添加引导页面:指导用户开启必要的权限
-
自启动权限:引导用户手动授权
-
电池优化白名单:引导用户将应用加入电池优化白名单
-
后台保活:谨慎使用后台服务保持连接
javascript// 引导用户设置权限 function guideUserToSettings() { uni.showModal({ title: '推送设置提示', content: '为了确保能及时收到消息,请按以下步骤设置:\n1. 允许应用自启动\n2. 关闭电池优化\n3. 锁定应用在后台', confirmText: '去设置', success: (res) => { if (res.confirm) { // 跳转到应用设置页面 plus.runtime.openURL(plus.runtime.getProperty('appid')); } } }); }总结
不上架应用市场完全可以实现推送,关键是:
-
Android:使用 UniPush,接受厂商通道不可用的现实,通过引导用户设置来优化体验
-
iOS:根据分发范围选择合适方案:
-
企业内部 → 企业签名
-
小范围测试 → AdHoc
-
较多测试用户 → TestFlight
-
公开分发 → 必须上架 App Store
-
阿斌
2025-11-16