8.3 KiB
8.3 KiB
iOS远程推送功能实施计划
项目概述
本文档详细描述了在现有NestJS项目中实现iOS远程推送功能的完整实施计划。该功能将使用Apple官方APNs服务,通过@parse/node-apn库与Apple推送服务进行通信。
技术选型
核心技术栈
- 推送服务: Apple官方APNs (Apple Push Notification service)
- Node.js库: @parse/node-apn (Trust Score: 9.8,支持HTTP/2)
- 认证方式: Token-based authentication (推荐)
- 数据库: MySQL (与现有项目保持一致)
依赖包
{
"@parse/node-apn": "^5.0.0",
"uuid": "^11.1.0" // 已存在
}
实施阶段
第一阶段:基础设施搭建
-
创建推送模块结构
- 创建
src/push-notifications/目录 - 设置模块、控制器、服务的基础结构
- 创建
-
数据库设计与实现
- 创建推送令牌表 (t_user_push_tokens)
- 创建推送消息表 (t_push_messages)
- 创建推送模板表 (t_push_templates)
- 编写数据库迁移脚本
-
APNs连接配置
- 配置APNs认证信息
- 实现APNs Provider服务
- 设置连接池和错误处理
第二阶段:核心功能实现
-
推送令牌管理
- 实现设备令牌注册/更新/注销
- 令牌有效性验证
- 无效令牌清理机制
-
推送消息发送
- 实现单个推送发送
- 实现批量推送发送
- 实现静默推送发送
-
推送模板系统
- 模板创建/更新/删除
- 模板渲染引擎
- 动态数据绑定
第三阶段:API接口开发
-
推送令牌管理API
- POST /api/push-notifications/register-token
- PUT /api/push-notifications/update-token
- DELETE /api/push-notifications/unregister-token
-
推送消息发送API
- POST /api/push-notifications/send
- POST /api/push-notifications/send-by-template
- POST /api/push-notifications/send-batch
-
推送模板管理API
- GET /api/push-notifications/templates
- POST /api/push-notifications/templates
- PUT /api/push-notifications/templates/:id
- DELETE /api/push-notifications/templates/:id
第四阶段:优化与监控
-
性能优化
- 连接池管理
- 批量处理优化
- 缓存策略实现
-
错误处理与重试
- APNs错误分类处理
- 指数退避重试机制
- 无效令牌自动清理
-
日志与监控
- 推送状态日志记录
- 性能指标监控
- 错误率统计
文件结构
src/push-notifications/
├── push-notifications.module.ts
├── push-notifications.controller.ts
├── push-notifications.service.ts
├── apns.provider.ts
├── push-token.service.ts
├── push-template.service.ts
├── push-message.service.ts
├── models/
│ ├── user-push-token.model.ts
│ ├── push-message.model.ts
│ └── push-template.model.ts
├── dto/
│ ├── register-device-token.dto.ts
│ ├── update-device-token.dto.ts
│ ├── send-push-notification.dto.ts
│ ├── send-push-by-template.dto.ts
│ ├── create-push-template.dto.ts
│ ├── update-push-template.dto.ts
│ └── push-response.dto.ts
├── interfaces/
│ ├── push-notification.interface.ts
│ ├── apns-config.interface.ts
│ └── push-stats.interface.ts
└── enums/
├── device-type.enum.ts
├── push-type.enum.ts
└── push-message-status.enum.ts
环境配置
环境变量
# APNs配置
APNS_KEY_ID=your_key_id
APNS_TEAM_ID=your_team_id
APNS_KEY_PATH=path/to/APNsAuthKey_XXXXXXXXXX.p8
APNS_BUNDLE_ID=com.yourcompany.yourapp
APNS_ENVIRONMENT=production # or sandbox
# 推送服务配置
PUSH_RETRY_LIMIT=3
PUSH_REQUEST_TIMEOUT=5000
PUSH_HEARTBEAT=60000
PUSH_BATCH_SIZE=100
APNs认证文件
- 需要从Apple开发者账号下载.p8格式的私钥文件
- 将私钥文件安全地存储在服务器上
数据库表结构
推送令牌表 (t_user_push_tokens)
CREATE TABLE t_user_push_tokens (
id VARCHAR(36) PRIMARY KEY DEFAULT (UUID()),
user_id VARCHAR(255) NOT NULL,
device_token VARCHAR(255) NOT NULL,
device_type ENUM('IOS', 'ANDROID') NOT NULL DEFAULT 'IOS',
app_version VARCHAR(50),
os_version VARCHAR(50),
device_name VARCHAR(255),
is_active BOOLEAN DEFAULT TRUE,
last_used_at DATETIME,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_user_id (user_id),
INDEX idx_device_token (device_token),
INDEX idx_user_device (user_id, device_token),
UNIQUE KEY uk_user_device_token (user_id, device_token)
);
推送消息表 (t_push_messages)
CREATE TABLE t_push_messages (
id VARCHAR(36) PRIMARY KEY DEFAULT (UUID()),
user_id VARCHAR(255) NOT NULL,
device_token VARCHAR(255) NOT NULL,
message_type VARCHAR(50) NOT NULL,
title VARCHAR(255),
body TEXT,
payload JSON,
push_type ENUM('ALERT', 'BACKGROUND', 'VOIP', 'LIVEACTIVITY') DEFAULT 'ALERT',
priority TINYINT DEFAULT 10,
expiry DATETIME,
collapse_id VARCHAR(64),
status ENUM('PENDING', 'SENT', 'FAILED', 'EXPIRED') DEFAULT 'PENDING',
apns_response JSON,
error_message TEXT,
sent_at DATETIME,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_user_id (user_id),
INDEX idx_status (status),
INDEX idx_created_at (created_at),
INDEX idx_message_type (message_type)
);
推送模板表 (t_push_templates)
CREATE TABLE t_push_templates (
id VARCHAR(36) PRIMARY KEY DEFAULT (UUID()),
template_key VARCHAR(100) NOT NULL UNIQUE,
title VARCHAR(255) NOT NULL,
body TEXT NOT NULL,
payload_template JSON,
push_type ENUM('ALERT', 'BACKGROUND', 'VOIP', 'LIVEACTIVITY') DEFAULT 'ALERT',
priority TINYINT DEFAULT 10,
is_active BOOLEAN DEFAULT TRUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_template_key (template_key),
INDEX idx_is_active (is_active)
);
使用示例
1. 注册设备令牌
// iOS客户端获取设备令牌后,调用此API
POST /api/push-notifications/register-token
{
"deviceToken": "a9d0ed10e9cfd022a61cb08753f49c5a0b0dfb383697bf9f9d750a1003da19c7",
"deviceType": "IOS",
"appVersion": "1.0.0",
"osVersion": "iOS 15.0",
"deviceName": "iPhone 13"
}
2. 发送推送通知
// 在业务服务中调用推送服务
await this.pushNotificationsService.sendNotification({
userIds: ['user_123'],
title: '训练提醒',
body: '您今天的普拉提训练还未完成,快来打卡吧!',
payload: {
type: 'training_reminder',
trainingId: 'training_123'
}
});
3. 使用模板发送推送
// 使用预定义模板发送推送
await this.pushNotificationsService.sendNotificationByTemplate(
'user_123',
'training_reminder',
{
userName: '张三',
trainingName: '核心力量训练'
}
);
预期收益
- 用户体验提升: 及时推送训练提醒、饮食记录等重要信息
- 用户粘性增强: 通过个性化推送提高用户活跃度
- 业务目标达成: 支持各种业务场景的推送需求
- 技术架构完善: 建立可扩展的推送服务架构
风险评估
技术风险
- APNs连接稳定性: 通过连接池和重试机制降低风险
- 推送令牌管理: 实现自动清理和验证机制
- 性能瓶颈: 通过批量处理和缓存优化解决
业务风险
- 用户隐私: 严格遵守数据保护法规
- 推送频率: 实现推送频率限制避免骚扰用户
- 内容审核: 建立推送内容审核机制
后续扩展
- 多平台支持: 扩展Android推送功能
- 推送策略: 实现智能推送时机和内容优化
- 数据分析: 推送效果分析和用户行为追踪
- A/B测试: 推送内容和策略的A/B测试功能
总结
本实施计划提供了一个完整的iOS远程推送功能解决方案,包括技术选型、架构设计、实施步骤和使用示例。该方案具有良好的可扩展性和维护性,能够满足当前业务需求并为未来扩展留有空间。
实施完成后,您将拥有一个功能完整、性能优良的推送服务系统,可以通过简单的API调用来发送各种类型的推送通知,提升用户体验和业务指标。