Class: RubyPushNotifications::APNS::APNSPusher

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby-push-notifications/apns/apns_pusher.rb

Overview

This class coordinates the process of sending notifications. It takes care of reopening closed APNSConnections and seeking back to the failed notification to keep writing.

Remember that APNS doesn’t confirm successful notification, it just notifies when one went wrong and closes the connection. Therefore, this APNSPusher reconnects and rewinds the array until the notification that Apple rejected.

Author:

  • Carlos Alonso

Instance Method Summary collapse

Constructor Details

#initialize(certificate, sandbox, password = nil, options = {}) ⇒ APNSPusher

Returns a new instance of APNSPusher.

Parameters:

  • certificate (String)

    . The PEM encoded APNS certificate.

  • sandbox (Boolean)

    . Whether the certificate is an APNS sandbox or not.

  • options (Hash) (defaults to: {})

    optional. Options for APNSPusher. Currently supports:

    • host [String]: Hostname of the APNS environment. Defaults to the official APNS hostname.

    • connect_timeout [Integer]: Number of seconds to wait for the connection to open. Defaults to 30.



21
22
23
24
25
26
# File 'lib/ruby-push-notifications/apns/apns_pusher.rb', line 21

def initialize(certificate, sandbox, password = nil, options = {})
  @certificate = certificate
  @pass = password
  @sandbox = sandbox
  @options = options
end

Instance Method Details

#push(notifications) ⇒ Object

Pushes the notifications. Builds an array with all the binaries (one for each notification and receiver) and pushes them sequentially to APNS monitoring the response. If an error is received, the connection is reopened and the process continues at the next notification after the failed one (pointed by the response error)

For each notification assigns an array with the results of each submission.

Parameters:

  • notifications (Array)

    . All the APNSNotifications to be sent.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/ruby-push-notifications/apns/apns_pusher.rb', line 37

def push(notifications)
  conn = APNSConnection.open @certificate, @sandbox, @pass, @options

  binaries = notifications.each_with_object([]) do |notif, binaries|
    notif.each_message(binaries.count) do |msg|
      binaries << msg
    end
  end

  results = []
  i = 0
  while i < binaries.count
    conn.write binaries[i]

    if i == binaries.count-1
      conn.flush
      rs, = IO.select([conn], nil, nil, 2)
    else
      rs, = IO.select([conn], [conn])
    end
    if rs && rs.any?
      packed = rs[0].read 6
      if packed.nil? && i == 0
        # The connection wasn't properly open
        # Probably because of wrong certificate/sandbox? combination
        results << UNKNOWN_ERROR_STATUS_CODE
      else
        err = packed.unpack 'ccN'
        results.slice! err[2]..-1
        results << err[1]
        i = err[2]
        conn = APNSConnection.open @certificate, @sandbox, @pass, @options
      end
    else
      results << NO_ERROR_STATUS_CODE
    end
    i += 1
  end

  conn.close

  notifications.each do |notif|
    notif.results = APNSResults.new(results.slice! 0, notif.count)
  end
end