Class: APN::Notification

Inherits:
Object
  • Object
show all
Defined in:
lib/apn/notification.rb

Overview

Encapsulates the logic necessary to convert an iPhone token and an array of options into a string of the format required by Apple’s servers to send the notification. Much of the processing code here copied with many thanks from github.com/samsoffes/apple_push_notification/blob/master/lib/apple_push_notification.rb

APN::Notification.new’s first argument is the token of the iPhone which should receive the notification. The second argument is a hash with any of :alert, :badge, and :sound keys. All three accept string arguments, while :sound can also be set to true to play the default sound installed with the application. At least one of these keys must exist. Any other keys are merged into the root of the hash payload ultimately sent to the iPhone:

APN::Notification.new(token, {:alert => 'Stuff', :custom => {:code => 23}})
# Writes this JSON to servers: {"aps" => {"alert" => "Stuff"}, "custom" => {"code" => 23}}

As a shortcut, APN::Notification.new also accepts a string as the second argument, which it converts into the alert to send. The following two lines are equivalent:

APN::Notification.new(token, 'Some Alert')
APN::Notification.new(token, {:alert => 'Some Alert'})

Constant Summary collapse

DATA_MAX_BYTES =

Available to help clients determine before they create the notification if their message will be too large. Each iPhone Notification payload must be 256 or fewer characters (not including the token or other push data), see Apple specs at: developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/CommunicatingWIthAPS.html#//apple_ref/doc/uid/TP40008194-CH101-SW4

256

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(token, opts) ⇒ Notification

Returns a new instance of Notification.



27
28
29
30
31
32
# File 'lib/apn/notification.rb', line 27

def initialize(token, opts)
  @options = opts.is_a?(Hash) ? opts.symbolize_keys : {:alert => opts}
  @token = token

  raise "The maximum size allowed for a notification payload is #{DATA_MAX_BYTES} bytes." if payload_size > DATA_MAX_BYTES
end

Instance Attribute Details

#optionsObject

Returns the value of attribute options.



26
27
28
# File 'lib/apn/notification.rb', line 26

def options
  @options
end

#tokenObject

Returns the value of attribute token.



26
27
28
# File 'lib/apn/notification.rb', line 26

def token
  @token
end

Instance Method Details

#packaged_messageObject

Converts the supplied options into the JSON needed for Apple’s push notification servers. Extracts :alert, :badge, and :sound keys into the ‘aps’ hash, merges any other hash data into the root of the hash to encode and send to apple.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/apn/notification.rb', line 63

def packaged_message
  @packaged_message ||=
    begin
      opts = @options.dup
      hsh = {'aps' => {}}
      if alert = opts.delete(:alert)
        alert = alert.to_s unless alert.is_a?(Hash)
        hsh['aps']['alert'] = alert
      end
      hsh['aps']['badge'] = opts.delete(:badge).to_i if opts[:badge]
      if sound = opts.delete(:sound)
        hsh['aps']['sound'] = sound.is_a?(TrueClass) ? 'default' : sound.to_s
      end
      hsh.merge!(opts)
      payload(hsh)
    end
end

#packaged_notificationObject

Completed encoded notification, ready to send down the wire to Apple



49
50
51
52
53
# File 'lib/apn/notification.rb', line 49

def packaged_notification
  pt = packaged_token
  pm = packaged_message
  [0, 0, 32, pt, 0, payload_size, pm].pack("ccca*cca*")
end

#packaged_tokenObject

Device token, compressed and hex-ified



56
57
58
# File 'lib/apn/notification.rb', line 56

def packaged_token
  [@token.gsub(/[\s|<|>]/,'')].pack('H*')
end

#payload_sizeObject



38
39
40
# File 'lib/apn/notification.rb', line 38

def payload_size
  packaged_message.bytesize
end

#to_sObject



34
35
36
# File 'lib/apn/notification.rb', line 34

def to_s
  packaged_notification
end

#valid?Boolean

Ensures at least one of %w(alert badge sound) is present

Returns:

  • (Boolean)


43
44
45
46
# File 'lib/apn/notification.rb', line 43

def valid?
  return true if [:alert, :badge, :sound].any?{|key| options.keys.include?(key) }
  false
end