apple_apns/
header.rs

1use http::header::{HeaderName, HeaderValue};
2use serde::{Deserialize, Serialize};
3use serde_plain::{derive_display_from_serialize, derive_fromstr_from_deserialize};
4use serde_repr::{Deserialize_repr, Serialize_repr};
5
6/// Payload size limit for message types other than VoIP.
7pub const PAYLOAD_SIZE_LIMIT: usize = 4096;
8
9/// Payload size limit for the VoIP message type.
10pub const VOIP_PAYLOAD_SIZE_LIMIT: usize = 5120;
11
12/// (Required for watchOS 6 and later; recommended for macOS, iOS, tvOS, and
13/// iPadOS) The value of this header must accurately reflect the contents of
14/// your notification’s payload. If there’s a mismatch, or if the header is
15/// missing on required systems, APNs may return an error, delay the delivery of
16/// the notification, or drop it altogether.
17pub static APNS_PUSH_TYPE: HeaderName = HeaderName::from_static("apns-push-type");
18
19/// A canonical UUID that is the unique ID for the notification. If an error
20/// occurs when sending the notification, APNs includes this value when
21/// reporting the error to your server. Canonical UUIDs are 32 lowercase
22/// hexadecimal digits, displayed in five groups separated by hyphens in the
23/// form 8-4-4-4-12. For example: 123e4567-e89b-12d3-a456-4266554400a0. If you
24/// omit this header, APNs creates a UUID for you and returns it in its
25/// response.
26pub static APNS_ID: HeaderName = HeaderName::from_static("apns-id");
27
28/// The date at which the notification is no longer valid. This value is a UNIX
29/// epoch expressed in seconds (UTC). If the value is nonzero, APNs stores the
30/// notification and tries to deliver it at least once, repeating the attempt as
31/// needed until the specified date. If the value is 0, APNs attempts to deliver
32/// the notification only once and doesn’t store it.
33///
34/// A single APNs attempt may involve retries over multiple network interfaces
35/// and connections of the destination device. Often these retries span over
36/// some time period, depending on the network characteristics. In addition, a
37/// push notification may take some time on the network after APNs sends it to
38/// the device. APNs uses best efforts to honor the expiry date without any
39/// guarantee. If the value is nonzero, the notification may be delivered after
40/// the mentioned date. If the value is 0, the notification may be delivered
41/// with some delay.
42pub static APNS_EXPIRATION: HeaderName = HeaderName::from_static("apns-expiration");
43
44/// The priority of the notification. If you omit this header, APNs sets the
45/// notification priority to 10.
46///
47/// Specify 10 to send the notification immediately.
48///
49/// Specify 5 to send the notification based on power considerations on the
50/// user’s device.
51///
52/// Specify 1 to prioritize the device’s power considerations over all other
53/// factors for delivery, and prevent awakening the device.
54pub static APNS_PRIORITY: HeaderName = HeaderName::from_static("apns-priority");
55
56/// The topic for the notification. In general, the topic is your app’s bundle
57/// ID/app ID. It can have a suffix based on the type of push notification. If
58/// you’re using a certificate that supports PushKit VoIP or watchOS
59/// complication notifications, you must include this header with bundle ID of
60/// you app and if applicable, the proper suffix. If you’re using token-based
61/// authentication with APNs, you must include this header with the correct
62/// bundle ID and suffix combination. To learn more about app ID, see [Register
63/// an App ID](https://help.apple.com/developer-account/#/dev1b35d6f83).
64pub static APNS_TOPIC: HeaderName = HeaderName::from_static("apns-topic");
65
66/// An identifier you use to coalesce multiple notifications into a single
67/// notification for the user. Typically, each notification request causes a new
68/// notification to be displayed on the user’s device. When sending the same
69/// notification more than once, use the same value in this header to coalesce
70/// the requests. The value of this key must not exceed 64 bytes.
71pub static APNS_COLLAPSE_ID: HeaderName = HeaderName::from_static("apns-collapse-id");
72
73/// Use the `alert` push type for notifications that trigger a user
74/// interaction—for example, an alert, badge, or sound. If you set this push
75/// type, the `apns-topic` header field must use your app’s bundle ID as the
76/// topic. For more information, see [Generating a remote
77/// notification](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification).
78///
79/// If the notification requires immediate action from the user, set
80/// notification priority to 10; otherwise use 5.
81///
82/// The `alert` push type is required on watchOS 6 and later. It is recommended
83/// on macOS, iOS, tvOS, and iPadOS.
84pub static ALERT: HeaderValue = HeaderValue::from_static("alert");
85
86/// Use the `background` push type for notifications that deliver content in the
87/// background, and don’t trigger any user interactions. If you set this push
88/// type, the `apns-topic header` field must use your app’s bundle ID as the
89/// topic. Always use priority 5. Using priority 10 is an error. For more
90/// information, see [Pushing Background Updates to Your
91/// App](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/pushing_background_updates_to_your_app).
92///
93/// The `background` push type is required on watchOS 6 and later. It is
94/// recommended on macOS, iOS, tvOS, and iPadOS.
95pub static BACKGROUND: HeaderValue = HeaderValue::from_static("background");
96
97/// Use the `location` push type for notifications that request a user’s
98/// location. If you set this push type, the `apns-topic` header field must use
99/// your app’s bundle ID with `.location-query` appended to the end. For more
100/// information, see Creating a location push service extension.
101///
102/// The `location` push type is recommended for iOS and iPadOS. It isn’t
103/// available on macOS, tvOS, and watchOS.
104///
105/// If the location query requires an immediate response from the Location Push
106/// Service Extension, set notification `apns-priority` to 10; otherwise, use 5.
107///
108/// The `location` push type supports only token-based authentication.
109pub static LOCATION: HeaderValue = HeaderValue::from_static("location");
110
111/// Use the `voip` push type for notifications that provide information about an
112/// incoming Voice-over-IP (VoIP) call. For more information, see [Responding to
113/// VoIP Notifications from
114/// PushKit](https://developer.apple.com/documentation/pushkit/responding_to_voip_notifications_from_pushkit).
115///
116/// If you set this push type, the apns-topic header field must use your app’s
117/// bundle ID with `.voip` appended to the end. If you’re using
118/// certificate-based authentication, you must also register the certificate for
119/// VoIP services. The topic is then part of the 1.2.840.113635.100.6.3.4 or
120/// 1.2.840.113635.100.6.3.6 extension.
121///
122/// The `voip` push type is not available on watchOS. It is recommended on
123/// macOS, iOS, tvOS, and iPadOS.
124pub static VOIP: HeaderValue = HeaderValue::from_static("voip");
125
126/// Use the `complication` push type for notifications that contain update
127/// information for a watchOS app’s complications. For more information, see
128/// Keeping Your Complications Up to Date.
129///
130/// If you set this push type, the `apns-topic` header field must use your app’s
131/// bundle ID with `.complication` appended to the end. If you’re using
132/// certificate-based authentication, you must also register the certificate for
133/// WatchKit services. The topic is then part of the 1.2.840.113635.100.6.3.6
134/// extension.
135///
136/// The `complication` push type is recommended for watchOS and iOS. It is not
137/// available on macOS, tvOS, and iPadOS.
138pub static COMPLICATION: HeaderValue = HeaderValue::from_static("complication");
139
140/// Use the `fileprovider` push type to signal changes to a File Provider
141/// extension. If you set this push type, the `apns-topic` header field must use
142/// your app’s bundle ID with `.pushkit.fileprovider` appended to the end. For
143/// more information, see Using push notifications to signal changes.
144///
145/// The `fileprovider` push type is not available on watchOS. It is recommended
146/// on macOS, iOS, tvOS, and iPadOS.
147pub static FILEPROVIDER: HeaderValue = HeaderValue::from_static("fileprovider");
148
149/// Use the `mdm` push type for notifications that tell managed devices to
150/// contact the MDM server. If you set this push type, you must use the topic
151/// from the UID attribute in the subject of your MDM push certificate. For more
152/// information, see [Device
153/// Management](https://developer.apple.com/documentation/devicemanagement).
154///
155/// The mdm push type is not available on watchOS. It is recommended on macOS,
156/// iOS, tvOS, and iPadOS.
157pub static MDM: HeaderValue = HeaderValue::from_static("mdm");
158
159/// Send the notification immediately.
160pub static PRIORITY_IMMEDIATE: HeaderValue = HeaderValue::from_static("10");
161
162/// Send the notification based on power considerations on the user’s device
163pub static PRIORITY_CONSIDER_POWER: HeaderValue = HeaderValue::from_static("5");
164
165/// Prioritize the device’s power considerations over all other factors for
166/// delivery, and prevent awakening the device.
167pub static PRIORITY_PRIORITIZE_POWER: HeaderValue = HeaderValue::from_static("1");
168
169/// The `apns-push-type` header field has the following valid values. The
170/// descriptions below describe when and how to use these values.
171#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)]
172#[serde(rename_all = "kebab-case")]
173pub enum PushType {
174    /// Use the `alert` push type for notifications that trigger a user
175    /// interaction—for example, an alert, badge, or sound. If you set this push
176    /// type, the `apns-topic` header field must use your app’s bundle ID as the
177    /// topic. For more information, see [Generating a remote
178    /// notification](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification).
179    ///
180    /// If the notification requires immediate action from the user, set
181    /// notification priority to 10; otherwise use 5.
182    ///
183    /// The `alert` push type is required on watchOS 6 and later. It is
184    /// recommended on macOS, iOS, tvOS, and iPadOS.
185    Alert,
186
187    /// Use the `background` push type for notifications that deliver content in
188    /// the background, and don’t trigger any user interactions. If you set this
189    /// push type, the `apns-topic header` field must use your app’s bundle ID
190    /// as the topic. Always use priority 5. Using priority 10 is an error. For
191    /// more information, see [Pushing Background Updates to Your
192    /// App](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/pushing_background_updates_to_your_app).
193    ///
194    /// The `background` push type is required on watchOS 6 and later. It is
195    /// recommended on macOS, iOS, tvOS, and iPadOS.
196    Background,
197
198    /// Use the `location` push type for notifications that request a user’s
199    /// location. If you set this push type, the `apns-topic` header field must
200    /// use your app’s bundle ID with `.location-query` appended to the end. For
201    /// more information, see Creating a location push service extension.
202    ///
203    /// The `location` push type is recommended for iOS and iPadOS. It isn’t
204    /// available on macOS, tvOS, and watchOS.
205    ///
206    /// If the location query requires an immediate response from the Location
207    /// Push Service Extension, set notification `apns-priority` to 10;
208    /// otherwise, use 5.
209    ///
210    /// The location push type supports only token-based authentication.
211    Location,
212
213    /// Use the `voip` push type for notifications that provide information
214    /// about an incoming Voice-over-IP (VoIP) call. For more information, see
215    /// [Responding to VoIP Notifications from
216    /// PushKit](https://developer.apple.com/documentation/pushkit/responding_to_voip_notifications_from_pushkit).
217    ///
218    /// If you set this push type, the apns-topic header field must use your
219    /// app’s bundle ID with `.voip` appended to the end. If you’re using
220    /// certificate-based authentication, you must also register the certificate
221    /// for VoIP services. The topic is then part of the
222    /// 1.2.840.113635.100.6.3.4 or 1.2.840.113635.100.6.3.6 extension.
223    ///
224    /// The voip push type is not available on watchOS. It is recommended on
225    /// macOS, iOS, tvOS, and iPadOS.
226    Voip,
227
228    /// Use the `complication` push type for notifications that contain update
229    /// information for a watchOS app’s complications. For more information, see
230    /// Keeping Your Complications Up to Date.
231    ///
232    /// If you set this push type, the `apns-topic` header field must use your
233    /// app’s bundle ID with `.complication` appended to the end. If you’re
234    /// using certificate-based authentication, you must also register the
235    /// certificate for WatchKit services. The topic is then part of the
236    /// 1.2.840.113635.100.6.3.6 extension.
237    ///
238    /// The `complication` push type is recommended for watchOS and iOS. It is
239    /// not available on macOS, tvOS, and iPadOS.
240    Complication,
241
242    /// Use the `fileprovider` push type to signal changes to a File Provider
243    /// extension. If you set this push type, the `apns-topic` header field must
244    /// use your app’s bundle ID with `.pushkit.fileprovider` appended to the
245    /// end. For more information, see Using push notifications to signal
246    /// changes.
247    ///
248    /// The `fileprovider` push type is not available on watchOS. It is
249    /// recommended on macOS, iOS, tvOS, and iPadOS.
250    Fileprovider,
251
252    /// Use the `mdm` push type for notifications that tell managed devices to
253    /// contact the MDM server. If you set this push type, you must use the
254    /// topic from the UID attribute in the subject of your MDM push
255    /// certificate. For more information, see [Device
256    /// Management](https://developer.apple.com/documentation/devicemanagement).
257    ///
258    /// The mdm push type is not available on watchOS. It is recommended on
259    /// macOS, iOS, tvOS, and iPadOS.
260    Mdm,
261}
262
263impl Default for PushType {
264    fn default() -> Self {
265        Self::Alert
266    }
267}
268
269impl From<PushType> for HeaderValue {
270    fn from(apns_push_type: PushType) -> Self {
271        match apns_push_type {
272            PushType::Alert => ALERT.clone(),
273            PushType::Background => BACKGROUND.clone(),
274            PushType::Location => LOCATION.clone(),
275            PushType::Voip => VOIP.clone(),
276            PushType::Complication => COMPLICATION.clone(),
277            PushType::Fileprovider => FILEPROVIDER.clone(),
278            PushType::Mdm => MDM.clone(),
279        }
280    }
281}
282
283derive_fromstr_from_deserialize!(PushType);
284derive_display_from_serialize!(PushType);
285
286impl PushType {
287    pub fn payload_size_limit(&self) -> usize {
288        if *self == PushType::Voip {
289            VOIP_PAYLOAD_SIZE_LIMIT
290        } else {
291            PAYLOAD_SIZE_LIMIT
292        }
293    }
294}
295
296/// Push notification priority.
297#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize_repr, Serialize_repr)]
298#[repr(u8)]
299pub enum Priority {
300    /// Send the notification immediately.
301    Immediate = 10,
302
303    /// Send the notification based on power considerations on the user’s device
304    ConsiderPower = 5,
305
306    /// Prioritize the device’s power considerations over all other factors for
307    /// delivery, and prevent awakening the device.
308    PrioritizePower = 1,
309}
310
311impl Default for Priority {
312    fn default() -> Self {
313        Self::Immediate
314    }
315}
316
317impl From<Priority> for HeaderValue {
318    fn from(this: Priority) -> Self {
319        match this {
320            Priority::Immediate => PRIORITY_IMMEDIATE.clone(),
321            Priority::ConsiderPower => PRIORITY_CONSIDER_POWER.clone(),
322            Priority::PrioritizePower => PRIORITY_PRIORITIZE_POWER.clone(),
323        }
324    }
325}
326
327derive_fromstr_from_deserialize!(Priority);
328derive_display_from_serialize!(Priority);