module Rpush::Client::ActiveModel::Apns::Notification

Constants

APNS_DEFAULT_EXPIRY
APNS_PRIORITIES
APNS_PRIORITY_CONSERVE_POWER
APNS_PRIORITY_IMMEDIATE
CONTENT_AVAILABLE_KEY
MAX_PAYLOAD_BYTESIZE
MDM_KEY
MUTABLE_CONTENT_KEY

Public Class Methods

included(base) click to toggle source
# File lib/rpush/client/active_model/apns/notification.rb, line 18
def self.included(base)
  base.extend ClassMethods
  base.instance_eval do
    validates :device_token, presence: true
    validates :badge, numericality: true, allow_nil: true
    validates :priority, inclusion: { in: APNS_PRIORITIES }, allow_nil: true

    validates_with Rpush::Client::ActiveModel::Apns::DeviceTokenFormatValidator
    validates_with Rpush::Client::ActiveModel::Apns::NotificationPayloadSizeValidator

    base.const_set('APNS_DEFAULT_EXPIRY', APNS_DEFAULT_EXPIRY) unless base.const_defined?('APNS_DEFAULT_EXPIRY')
    base.const_set('APNS_PRIORITY_IMMEDIATE', APNS_PRIORITY_IMMEDIATE) unless base.const_defined?('APNS_PRIORITY_IMMEDIATE')
    base.const_set('APNS_PRIORITY_CONSERVE_POWER', APNS_PRIORITY_CONSERVE_POWER) unless base.const_defined?('APNS_PRIORITY_CONSERVE_POWER')
  end
end

Public Instance Methods

as_json(options = nil) click to toggle source
# File lib/rpush/client/active_model/apns/notification.rb, line 55
def as_json(options = nil) # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
  json = ActiveSupport::OrderedHash.new

  if data && data.key?(MDM_KEY)
    json['mdm'] = data[MDM_KEY]
  else
    json['aps'] = ActiveSupport::OrderedHash.new
    json['aps']['alert'] = alert if alert
    json['aps']['badge'] = badge if badge
    json['aps']['sound'] = sound if sound
    json['aps']['category'] = category if category
    json['aps']['url-args'] = url_args if url_args
    json['aps']['thread-id'] = thread_id if thread_id

    if data && data[MUTABLE_CONTENT_KEY]
      json['aps']['mutable-content'] = 1
    end

    if data && data[CONTENT_AVAILABLE_KEY]
      json['aps']['content-available'] = 1
    end

    if data
      non_aps_attributes = data.reject { |k, _| k == CONTENT_AVAILABLE_KEY || k == MUTABLE_CONTENT_KEY }
      non_aps_attributes.each { |k, v| json[k.to_s] = v }
    end
  end

  json
end
content_available=(bool) click to toggle source
# File lib/rpush/client/active_model/apns/notification.rb, line 50
def content_available=(bool)
  return unless bool
  self.data = (data || {}).merge(CONTENT_AVAILABLE_KEY => true)
end
device_token=(token) click to toggle source
# File lib/rpush/client/active_model/apns/notification.rb, line 34
def device_token=(token)
  write_attribute(:device_token, token.delete(" <>")) unless token.nil?
end
mdm=(magic) click to toggle source
# File lib/rpush/client/active_model/apns/notification.rb, line 39
def mdm=(magic)
  self.data = (data || {}).merge(MDM_KEY => magic)
end
mutable_content=(bool) click to toggle source
# File lib/rpush/client/active_model/apns/notification.rb, line 44
def mutable_content=(bool)
  return unless bool
  self.data = (data || {}).merge(MUTABLE_CONTENT_KEY => true)
end
to_binary(options = {}) click to toggle source
# File lib/rpush/client/active_model/apns/notification.rb, line 86
def to_binary(options = {})
  frame_payload = payload
  frame_id = options[:for_validation] ? 0 : send(options.fetch(:id_attribute, :id))
  frame = ""
  frame << [1, 32, device_token].pack("cnH*")
  frame << [2, frame_payload.bytesize, frame_payload].pack("cna*")
  frame << [3, 4, frame_id].pack("cnN")
  frame << [4, 4, expiry ? Time.now.to_i + expiry.to_i : 0].pack("cnN")
  frame << [5, 1, priority_for_frame].pack("cnc")
  [2, frame.bytesize].pack("cN") + frame
end

Private Instance Methods

priority_for_frame() click to toggle source
# File lib/rpush/client/active_model/apns/notification.rb, line 100
def priority_for_frame
  # It is an error to use APNS_PRIORITY_IMMEDIATE for a notification that only contains content-available.
  if as_json['aps'].try(:keys) == ['content-available']
    APNS_PRIORITY_CONSERVE_POWER
  else
    priority || APNS_PRIORITY_IMMEDIATE
  end
end