Устаревшая информация
Новая разработка должна использовать современный формат для соединения с APNs, как описано в Двоичном Формате Интерфейса и Уведомления.
Эти форматы не включают приоритет; приоритет 10
принят.
Простой формат уведомления
Рисунок a-1 показывает этот формат.
Первый байт в унаследованном формате является значением команды 0 (нуль). Другие поля совпадают с улучшенным форматом. Перечисление a-1 дает пример функции, отправляющей удаленное уведомление APNs по двоичному интерфейсу с помощью простого формата уведомления. Пример принимает предшествующее соединение SSL с gateway.push.apple.com
(или gateway.sandbox.push.apple.com
) и аутентификация удаленной станции.
Перечисление a-1 , Отправляющее уведомление в простом формате через двоичный интерфейс
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; |
} |
Улучшенный формат уведомления
Улучшенный формат имеет несколько улучшений по сравнению с простым форматом:
Ошибочный ответ. С простым форматом при отправке пакета уведомления, который уродлив в некотором роде — например, полезная нагрузка превышает предусмотренный предел — APNs отвечает путем разъединения соединения. Это не дает индикации, почему это отклонило уведомление. Улучшенный формат позволяет провайдеру тегировать уведомление с произвольным идентификатором. Если существует ошибка, APNs возвращает пакет, связывающий код ошибки с идентификатором. Этот ответ позволяет провайдеру определить местоположение и исправить уродливое уведомление.
Истечение срока уведомления. APNs имеет функцию промежуточной буферизации, сохраняющую новое уведомление отправленным в приложение на устройстве. Если устройство является оффлайновым во время поставки, APNs поставляет уведомление, когда устройство затем прибывает онлайн. С простым форматом уведомление поставлено независимо от уместности уведомления. Другими словами, уведомление может стать «устаревшим» в течение долгого времени. Улучшенный формат включает значение истечения, указывающее срок действия для уведомления. Когда этот период истекает, APNs отбрасывает уведомление в промежуточной буферизации.
Рисунок a-2 изображает формат для пакетов уведомления.
Первый байт в формате уведомления является значением команды 1. Остающиеся поля следующие:
Идентификатор — произвольное значение, идентифицирующее это уведомление. Если APNs не может интерпретировать уведомление, этот тот же идентификатор возвращается в ошибочном ответном пакете.
Истечение — фиксированная опорная дата UNIX выразила в секундах (UTC), идентифицирующий, когда уведомление больше не действительно и может быть отброшено. Значение истечения использует сетевой порядок байтов (обратный порядок байтов). Если значение истечения является ненулевым, APNs пытается поставить уведомление, по крайней мере, один раз. Укажите нуль, чтобы запросить, чтобы APNs не сохранили уведомление вообще.
Маркерная длина — длина маркера устройства в сетевом порядке (т.е. обратный порядок байтов)
Маркер устройства — маркер устройства в двоичной форме.
Длина полезной нагрузки — длина полезной нагрузки в сетевом порядке (т.е. обратный порядок байтов). Полезная нагрузка не должна превышать 256 байтов и не должна быть завершена нулем.
Полезная нагрузка — полезная нагрузка уведомления.
Перечисление a-2 составляет удаленное уведомление в улучшенном формате прежде, чем отправить его в APNs. Это принимает предшествующее соединение SSL с gateway.push.apple.com
(или gateway.sandbox.push.apple.com
) и аутентификация удаленной станции.
Перечисление a-2 , Отправляющее уведомление в улучшенном формате через двоичный интерфейс
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; |
} |