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) ⇒ 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.


18
19
20
21
# File 'lib/ruby-push-notifications/apns/apns_pusher.rb', line 18

def initialize(certificate, sandbox)
  @certificate = certificate
  @sandbox = sandbox
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.


32
33
34
35
36
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
# File 'lib/ruby-push-notifications/apns/apns_pusher.rb', line 32

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

  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?
      err = rs[0].read(6).unpack 'ccN'
      results.slice! err[2]..-1
      results << err[1]
      i = err[2]
      conn = APNSConnection.open @certificate, @sandbox
    else
      results << NO_ERROR_STATUS_CODE
    end
    i += 1
  end

  conn.close

  notifications.each do |notif|
    notif.results = results.slice! 0, notif.count
  end
end