module ProMotion::IAP

Attributes

completion_handlers[RW]

Public Instance Methods

paymentQueue(_, updatedTransactions:transactions) click to toggle source

SKPaymentTransactionObserver methods

# File lib/ProMotion/iap.rb, line 154
def paymentQueue(_, updatedTransactions:transactions)
  transactions.each do |transaction|
    case transaction.transactionState
    when SKPaymentTransactionStatePurchasing  then iap_callback(:in_progress, transaction)
    when SKPaymentTransactionStateDeferred    then iap_callback(:deferred,    transaction)
    when SKPaymentTransactionStatePurchased   then iap_callback(:purchased,   transaction, true)
    when SKPaymentTransactionStateRestored    then iap_callback(:restored,    transaction, true)
    when SKPaymentTransactionStateFailed
      if transaction.error.code == SKErrorPaymentCancelled
        iap_callback(:canceled, transaction, true)
      else
        iap_callback(:error, transaction, true)
      end
    end
  end
  iap_shutdown if transaction_complete?(transactions)
end
productsRequest(_, didReceiveResponse:response) click to toggle source

SKProductsRequestDelegate methods

# File lib/ProMotion/iap.rb, line 135
def productsRequest(_, didReceiveResponse:response)
  unless response.invalidProductIdentifiers.empty?
    red = "\e[0;31m"
    color_off = "\e[0m"
  end
  retrieved_iaps_handler(response.products, &self.completion_handlers["retrieve_iaps"]) if self.completion_handlers["retrieve_iaps"]
  @products_request = nil
  self.completion_handlers["retrieve_iaps"] = nil
end
purchase_iap(product_ids, options={}, &callback)
Alias for: purchase_iaps
purchase_iaps(product_ids, options={}, &callback) click to toggle source
# File lib/ProMotion/iap.rb, line 5
def purchase_iaps(product_ids, options={}, &callback)
  iap_setup
  retrieve_iaps product_ids do |products|
    products.each do |product|
      self.completion_handlers["purchase-#{product[:product_id]}"] = callback

      payment = SKMutablePayment.paymentWithProduct(product[:product])
      payment.applicationUsername = options[:username] if options[:username]

      SKPaymentQueue.defaultQueue.addPayment(payment)
    end
  end
end
Also aliased as: purchase_iap
request(_, didFailWithError:error) click to toggle source
# File lib/ProMotion/iap.rb, line 145
def request(_, didFailWithError:error)
  self.completion_handlers["retrieve_iaps"].call([], error) if self.completion_handlers["retrieve_iaps"].arity == 2
  self.completion_handlers["retrieve_iaps"].call([]) if self.completion_handlers["retrieve_iaps"].arity < 2
  @products_request = nil
  self.completion_handlers["retrieve_iaps"] = nil
end
restore_iap(product_ids, options={}, &callback)
Alias for: restore_iaps
restore_iaps(product_ids, options={}, &callback) click to toggle source
# File lib/ProMotion/iap.rb, line 20
def restore_iaps(product_ids, options={}, &callback)
  iap_setup
  retrieve_iaps Array(product_ids) do |products|
    products.each do |product|
      self.completion_handlers["restore-#{product[:product_id]}"] = callback
    end
    self.completion_handlers["restore-all"] = callback # In case of error

    if options[:username]
      SKPaymentQueue.defaultQueue.restoreCompletedTransactionsWithApplicationUsername(options[:username])
    else
      SKPaymentQueue.defaultQueue.restoreCompletedTransactions
    end
  end
end
Also aliased as: restore_iap
retrieve_iap(*product_ids, &callback)
Alias for: retrieve_iaps
retrieve_iaps(*product_ids, &callback) click to toggle source
# File lib/ProMotion/iap.rb, line 37
def retrieve_iaps(*product_ids, &callback)
  iap_setup
  self.completion_handlers["retrieve_iaps"] = callback
  @products_request = SKProductsRequest.alloc.initWithProductIdentifiers(NSSet.setWithArray(product_ids.flatten))
  @products_request.delegate = self
  @products_request.start
end
Also aliased as: retrieve_iap

Private Instance Methods

formatted_iap_price(price, price_locale) click to toggle source
# File lib/ProMotion/iap.rb, line 81
def formatted_iap_price(price, price_locale)
  num_formatter = NSNumberFormatter.new
  num_formatter.setFormatterBehavior NSNumberFormatterBehaviorDefault
  num_formatter.setNumberStyle NSNumberFormatterCurrencyStyle
  num_formatter.setLocale price_locale
  num_formatter.stringFromNumber price
end
iap_callback(status, transaction, finish=false) click to toggle source
# File lib/ProMotion/iap.rb, line 89
def iap_callback(status, transaction, finish=false)
  product_id = transaction_product_id(transaction)

  if self.completion_handlers["purchase-#{product_id}"]
    self.completion_handlers["purchase-#{product_id}"].call status, mapped_transaction(transaction)
    self.completion_handlers["purchase-#{product_id}"] = nil if finish
  end

  if self.completion_handlers["restore-#{product_id}"]
    self.completion_handlers["restore-#{product_id}"].call status, mapped_transaction(transaction)
    self.completion_handlers["restore-#{product_id}"] = nil if finish
  end

  SKPaymentQueue.defaultQueue.finishTransaction(transaction) if finish
end
iap_setup() click to toggle source
# File lib/ProMotion/iap.rb, line 52
def iap_setup
  SKPaymentQueue.defaultQueue.addTransactionObserver(self)
end
iap_shutdown() click to toggle source
# File lib/ProMotion/iap.rb, line 56
def iap_shutdown
  @completion_handlers = nil
  SKPaymentQueue.defaultQueue.removeTransactionObserver(self)
end
mapped_transaction(transaction) click to toggle source
# File lib/ProMotion/iap.rb, line 105
def mapped_transaction(transaction)
  if transaction.respond_to?(:payment)
    {
      product_id:   transaction.payment.productIdentifier,
      error:        transaction.error,
      transaction:  transaction
    }
  else
    {
      product_id:   nil,
      error:        transaction,
      transaction:  nil
    }
  end
end
retrieved_iaps_handler(products, &callback) click to toggle source
# File lib/ProMotion/iap.rb, line 61
def retrieved_iaps_handler(products, &callback)
  sk_products = products.map do |sk_product|
    {
      product_id:               sk_product.productIdentifier,
      title:                    sk_product.localizedTitle,
      description:              sk_product.localizedDescription,
      formatted_price:          formatted_iap_price(sk_product.price, sk_product.priceLocale),
      price:                    sk_product.price,
      price_locale:             sk_product.priceLocale,
      downloadable:             sk_product.isDownloadable,
      download_content_lengths: sk_product.downloadContentLengths,
      download_content_version: sk_product.downloadContentVersion,
      product:                  sk_product,
    }
  end

  callback.call(sk_products, nil) if callback.arity == 2
  callback.call(sk_products) if callback.arity < 2
end
transaction_complete?(transactions) click to toggle source
# File lib/ProMotion/iap.rb, line 125
def transaction_complete?(transactions)
  states = transactions.map(&:transactionState)
  return true unless states.include?(SKPaymentTransactionStatePurchasing)
  false
end
transaction_product_id(transaction) click to toggle source
# File lib/ProMotion/iap.rb, line 121
def transaction_product_id(transaction)
  transaction.respond_to?(:payment) ? transaction.payment.productIdentifier : "all"
end