版本记录
版本号 | 时间 |
---|---|
V1.0 | 2018.07.15 |
前言
我们做APP很多时候都需要推送功能,以直播为例,如果你关注的主播开播了,那么就需要向关注这个主播的人发送开播通知,提醒用户去看播,这个只是一个小的方面,具体应用根据公司的业务逻辑而定。前面已经花了很多篇幅介绍了极光推送,其实极光推送无非就是将我们客户端和服务端做的很多东西封装了一下,节省了我们很多处理逻辑和流程,这一篇开始,我们就利用系统的原生推送类结合工程实践说一下系统推送的集成,希望我的讲解能让大家很清楚的理解它。感兴趣的可以看上面几篇。
1. 系统推送的集成(一) —— 基本集成流程(一)
2. 系统推送的集成(二) —— 推送遇到的几个坑之BadDeviceToken问题(一)
3. 系统推送的集成(三) —— 本地和远程通知编程指南之你的App的通知 - 本地和远程通知概览(一)
4. 系统推送的集成(四) —— 本地和远程通知编程指南之你的App的通知 - 管理您的应用程序的通知支持(二)
5. 系统推送的集成(五) —— 本地和远程通知编程指南之你的App的通知 - 调度和处理本地通知(三)
6. 系统推送的集成(六) —— 本地和远程通知编程指南之你的App的通知 - 配置远程通知支持(四)
7. 系统推送的集成(七) —— 本地和远程通知编程指南之你的App的通知 - 修改和显示通知(五)
8. 系统推送的集成(八) —— 本地和远程通知编程指南之苹果推送通知服务APNs - APNs概览(一)
9. 系统推送的集成(九) —— 本地和远程通知编程指南之苹果推送通知服务APNs - 创建远程通知Payload(二)
10. 系统推送的集成(十) —— 本地和远程通知编程指南之苹果推送通知服务APNs - 与APNs通信(三)
11. 系统推送的集成(十一) —— 本地和远程通知编程指南之苹果推送通知服务APNs - Payload Key参考(四)
12. 系统推送的集成(十二) —— 本地和远程通知编程指南之Legacy信息 - 二进制Provider API(一)
Legacy Notification Format - Legacy通知格式
新开发应使用现代格式连接到APNs,如 Communicating with APNs中所述。
这些格式不包括优先权; 假设优先级为10。
图B-1显示了这种格式。
legacy格式中的第一个字节是命令值0(零)。 其他字段与增强格式相同。 Listing B-1
给出了一个函数示例,该函数使用legacy通知格式通过二进制接口向APNs发送远程通知。 该示例假设先前SSL连接到gateway.push.apple.com
(或gateway.sandbox.push.apple.com
)和对等交换验证。
// Listing B-1 Sending a notification in the legacy format via the binary interface
static bool sendPayload(SSL *sslPtr, char *deviceTokenBinary, char *payloadBuff, size_t payloadLength)
{
bool rtn = false;
if (sslPtr && deviceTokenBinary && payloadBuff && payloadLength)
{
uint8_t command = 0; /* command number */
char binaryMessageBuff[sizeof(uint8_t) + sizeof(uint16_t) +
DEVICE_BINARY_SIZE + sizeof(uint16_t) + MAXPAYLOAD_SIZE];
/* message format is, |COMMAND|TOKENLEN|TOKEN|PAYLOADLEN|PAYLOAD| */
char *binaryMessagePt = binaryMessageBuff;
uint16_t networkOrderTokenLength = htons(DEVICE_BINARY_SIZE);
uint16_t networkOrderPayloadLength = htons(payloadLength);
/* command */
*binaryMessagePt++ = command;
/* token length network order */
memcpy(binaryMessagePt, &networkOrderTokenLength, sizeof(uint16_t));
binaryMessagePt += sizeof(uint16_t);
/* device token */
memcpy(binaryMessagePt, deviceTokenBinary, DEVICE_BINARY_SIZE);
binaryMessagePt += DEVICE_BINARY_SIZE;
/* payload length network order */
memcpy(binaryMessagePt, &networkOrderPayloadLength, sizeof(uint16_t));
binaryMessagePt += sizeof(uint16_t);
/* payload */
memcpy(binaryMessagePt, payloadBuff, payloadLength);
binaryMessagePt += payloadLength;
if (SSL_write(sslPtr, binaryMessageBuff, (binaryMessagePt - binaryMessageBuff)) > 0)
rtn = true;
}
return rtn;
}
Enhanced Notification Format - 增强的通知格式
增强格式与legacy
格式相比有几处改进:
Error response - 错误响应。使用
legacy
格式,如果您发送以某种方式格式错误的通知数据包 - 例如,有效负载超出规定的限制 - APNs通过切断连接进行响应。它没有说明它拒绝通知的原因。增强格式允许提供者使用任意标识符标记通知。如果存在错误,APNs将返回将错误代码与标识符相关联的数据包。此响应使provider
能够定位并更正格式错误的通知。Notification expiration - 通知到期。 APNs具有存储转发功能,可将最新通知发送到设备上的应用程序。如果设备在交付时处于脱机状态,则APNs会在设备下次联机时发送通知。使用
legacy
格式,无论通知的相关性如何,都会发送通知。换句话说,通知随着时间的推移会变得“陈旧”。增强格式包括指示通知有效期的到期值。当此期限到期时,APNs会在存储转发中丢弃通知。
图B-2描述了通知数据包的格式。
通知格式中的第一个字节是命令值1,其余字段如下:
Identifier - 标识符 - 标识此通知的任意值。 如果APNs无法解释通知,则在错误响应数据包中返回相同的标识符。
Expiry - 到期 - 以秒(UTC)表示的固定UNIX纪元日期,用于标识通知何时不再有效且可以丢弃。 到期值使用网络字节顺序(大端)。 如果到期值非零,则APNs尝试至少传递一次通知。 指定零以请求APNs根本不存储通知。
Token length - 令牌长度 - 设备令牌网络顺序的长度(即大端)
Device token - 设备令牌 - 二进制形式的设备令牌。
Payload length - 有效负载长度 - 网络顺序中有效负载的长度(即大端)。 有效负载不得超过256个字节,且不得以空值终止。
Payload - 有效负载 - 通知负载。
Listing B-2
在将其发送到APNs之前以增强格式组成远程通知。 它假设优先SSL
连接到gateway.push.apple.com
(或gateway.sandbox.push.apple.com
)和对等交换验证。
// Listing B-2 Sending a notification in the enhanced format via the binary interface
static bool sendPayload(SSL *sslPtr, char *deviceTokenBinary, char *payloadBuff, size_t payloadLength)
{
bool rtn = false;
if (sslPtr && deviceTokenBinary && payloadBuff && payloadLength)
{
uint8_t command = 1; /* command number */
char binaryMessageBuff[sizeof(uint8_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint16_t) +
DEVICE_BINARY_SIZE + sizeof(uint16_t) + MAXPAYLOAD_SIZE];
/* message format is, |COMMAND|ID|EXPIRY|TOKENLEN|TOKEN|PAYLOADLEN|PAYLOAD| */
char *binaryMessagePt = binaryMessageBuff;
uint32_t whicheverOrderIWantToGetBackInAErrorResponse_ID = 1234;
uint32_t networkOrderExpiryEpochUTC = htonl(time(NULL)+86400); // expire message if not delivered in 1 day
uint16_t networkOrderTokenLength = htons(DEVICE_BINARY_SIZE);
uint16_t networkOrderPayloadLength = htons(payloadLength);
/* command */
*binaryMessagePt++ = command;
/* provider preference ordered ID */
memcpy(binaryMessagePt, &whicheverOrderIWantToGetBackInAErrorResponse_ID, sizeof(uint32_t));
binaryMessagePt += sizeof(uint32_t);
/* expiry date network order */
memcpy(binaryMessagePt, &networkOrderExpiryEpochUTC, sizeof(uint32_t));
binaryMessagePt += sizeof(uint32_t);
/* token length network order */
memcpy(binaryMessagePt, &networkOrderTokenLength, sizeof(uint16_t));
binaryMessagePt += sizeof(uint16_t);
/* device token */
memcpy(binaryMessagePt, deviceTokenBinary, DEVICE_BINARY_SIZE);
binaryMessagePt += DEVICE_BINARY_SIZE;
/* payload length network order */
memcpy(binaryMessagePt, &networkOrderPayloadLength, sizeof(uint16_t));
binaryMessagePt += sizeof(uint16_t);
/* payload */
memcpy(binaryMessagePt, payloadBuff, payloadLength);
binaryMessagePt += payloadLength;
if (SSL_write(sslPtr, binaryMessageBuff, (binaryMessagePt - binaryMessageBuff)) > 0)
rtn = true;
}
return rtn;
}
后记
本篇主要讲述了Legacy通知格式,感兴趣的给个赞或者关注~~~~