|
3 | 3 |
|
4 | 4 | module RubyPushNotifications |
5 | 5 | module APNS |
| 6 | + # Represents a APNS Notification. |
| 7 | + # Manages the conversion of the notification to APNS binary format for |
| 8 | + # each of the destinations. |
| 9 | + # By default sets maximum expiration date (4 weeks). |
| 10 | + # |
| 11 | + # @author Carlos Alonso |
6 | 12 | class APNSNotification |
7 | 13 |
|
8 | | - WEEKS_4 = 2419200 # 4 weeks |
| 14 | + # @private. 4 weeks in seconds |
| 15 | + WEEKS_4 = 2419200 |
9 | 16 |
|
| 17 | + # @return [Array]. Array with the results from sending this notification |
10 | 18 | attr_accessor :results |
11 | 19 |
|
| 20 | + # Initializes the APNS Notification |
| 21 | + # |
| 22 | + # @param [Array]. Array containing all destinations for the notification |
| 23 | + # @param [Hash]. Hash with the data to use as payload. |
12 | 24 | def initialize(tokens, data) |
13 | 25 | @tokens = tokens |
14 | 26 | @data = data |
15 | 27 | end |
16 | 28 |
|
| 29 | + # Method that yields the notification's binary for each of the receivers. |
| 30 | + # |
| 31 | + # @param starting_id [Integer]. Every notification encodes a unique ID for |
| 32 | + # further reference. This parameter represents the first id the first |
| 33 | + # notification of this group should use. |
| 34 | + # @yieldparam [String]. APNS binary's representation of this notification. |
| 35 | + # Consisting of: |
| 36 | + # Notification = 2(1), FrameLength(4), items(FrameLength) |
| 37 | + # Item = ItemID(1), ItemLength(2), data(ItemLength) |
| 38 | + # Items: |
| 39 | + # Device Token => Id: 1, length: 32, data: binary device token |
| 40 | + # Payload => Id: 2, length: ??, data: json formatted payload |
| 41 | + # Notification ID => Id: 3, length: 4, data: notif id as int |
| 42 | + # Expiration Date => Id: 4, length: 4, data: Unix timestamp as int |
| 43 | + # Priority => Id: 5, length: 1, data: 10 as 1 byte int |
| 44 | + # (https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/CommunicatingWIthAPS.html#//apple_ref/doc/uid/TP40008194-CH101-SW4) |
17 | 45 | def each_message(starting_id) |
18 | 46 | @tokens.each_with_index do |token, i| |
19 | | - # Notification = 2(1), FrameLength(4), items(FrameLength) |
20 | | - # Item = ItemID(1), ItemLength(2), data(ItemLength) |
21 | | - # Items: |
22 | | - # Device Token => Id: 1, length: 32, data: binary device token |
23 | | - # Payload => Id: 2, length: ??, data: json formatted payload |
24 | | - # Notification ID => Id: 3, length: 4, data: notif id as int |
25 | | - # Expiration Date => Id: 4, length: 4, data: Unix timestamp as int |
26 | | - # Priority => Id: 5, length: 1, data: 10 as 1 byte int |
27 | 47 | bytes = device_token(token) + payload + notification_id(starting_id + i) + expiration_date + priority |
28 | 48 | yield [2, bytes.bytesize, bytes].pack 'cNa*' |
29 | 49 | end |
30 | 50 | end |
31 | 51 |
|
| 52 | + # @return [Integer]. The number of binaries this notification will send. |
| 53 | + # One for each receiver. |
32 | 54 | def count |
33 | 55 | @tokens.count |
34 | 56 | end |
35 | 57 |
|
36 | 58 | private |
37 | 59 |
|
| 60 | + # @param [String]. The device token to encode. |
| 61 | + # @return [String]. Binary representation of the device token field. |
38 | 62 | def device_token(token) |
39 | 63 | [1, 32, token].pack 'cnH64' |
40 | 64 | end |
41 | 65 |
|
| 66 | + # Generates the APNS's binary representation of the notification's payload. |
| 67 | + # Caches the value in an instance variable. |
| 68 | + # |
| 69 | + # @return [String]. Binary representation of the notification's payload. |
42 | 70 | def payload |
43 | 71 | @encoded_payload ||= -> { |
44 | 72 | json = JSON.dump(@data).force_encoding 'ascii-8bit' |
45 | 73 | [2, json.bytesize, json].pack 'cna*' |
46 | 74 | }.call |
47 | 75 | end |
48 | 76 |
|
| 77 | + # @param [Integer]. The unique ID for this notification. |
| 78 | + # @return [String]. Binary representation of the notification id field. |
49 | 79 | def notification_id(id) |
50 | 80 | [3, 4, id].pack 'cnN' |
51 | 81 | end |
52 | 82 |
|
| 83 | + # @return [String]. Binary representation of the expiration date field. |
53 | 84 | def expiration_date |
54 | 85 | [4, 4, (Time.now + WEEKS_4).to_i].pack 'cnN' |
55 | 86 | end |
56 | 87 |
|
| 88 | + # @return [String]. Binary representation of the priority field. |
57 | 89 | def priority |
58 | 90 | [5, 1, 10].pack 'cnc' |
59 | 91 | end |
|
0 commit comments