ProMotion-iap 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +89 -0
- data/lib/ProMotion-iap.rb +11 -0
- data/lib/ProMotion/iap.rb +132 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b7e41cfc55cf06853a59e0f826b7161765189039
|
4
|
+
data.tar.gz: a2eba57b0b4f0d42ddd1fde6dd0f38c27c4f1bb6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ea6ebbe840ca8d1718d22a7f48706084917b62f1d8473d5e21550bdebdc53073bb76049def4d3f3fff77a613e0e0d410a21d66902c704f92abd61d5437bac9f1
|
7
|
+
data.tar.gz: 391efff17e8eb4ee1d5d9cd92f34469d59c6de8d8b9eb24fd8899437e2de2579cddf29e710a002f1fdb9a7d72436ad0f1192dd2fcb94dc3c04caed2c66bc8ce2
|
data/README.md
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
# ProMotion-iap
|
2
|
+
|
3
|
+
ProMotion-iap is in-app purchase notification support for the
|
4
|
+
popular RubyMotion gem [ProMotion](https://github.com/clearsightstudio/ProMotion).
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
gem 'ProMotion-iap'
|
10
|
+
```
|
11
|
+
|
12
|
+
## Usage
|
13
|
+
|
14
|
+
### AppDelegate
|
15
|
+
|
16
|
+
Include `PM::IAP` to add some in-app purchase methods to a screen, app delegate, or other class.
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
# app/screens/purchase_screen.rb
|
20
|
+
class PurchaseScreen < PM::Screen
|
21
|
+
include PM::IAP
|
22
|
+
|
23
|
+
def on_load
|
24
|
+
|
25
|
+
retrieve_iaps([ "productid1", "productid2" ]) do |products, error|
|
26
|
+
# products looks something like the following
|
27
|
+
[{
|
28
|
+
product_id: "productid1",
|
29
|
+
title: "title",
|
30
|
+
description: "description",
|
31
|
+
price: <BigDecimal 0.99>,
|
32
|
+
formatted_price: "$0.99",
|
33
|
+
price_locale: <NSLocale>,
|
34
|
+
downloadable: false,
|
35
|
+
download_content_lengths: <?>, # TODO: ?
|
36
|
+
download_content_version: <?>, # TODO: ?
|
37
|
+
product: <SKProduct>
|
38
|
+
}, {...}]
|
39
|
+
end
|
40
|
+
|
41
|
+
purchase_iap "productid" do |status, transaction|
|
42
|
+
case status
|
43
|
+
when :in_progress
|
44
|
+
# Usually do nothing, maybe a spinner
|
45
|
+
when :deferred
|
46
|
+
# Waiting on a prompt to the user
|
47
|
+
when :purchased
|
48
|
+
# Notify the user, update any affected UI elements
|
49
|
+
when :canceled
|
50
|
+
# They just canceled, no big deal.
|
51
|
+
when :error
|
52
|
+
# Failed to purchase
|
53
|
+
transaction.error.localizedDescription # => error message
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
restore_iaps do |status, products|
|
58
|
+
if status == :restored
|
59
|
+
# Update your UI, notify the user
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
```
|
67
|
+
|
68
|
+
#### purchase_iap(*product_ids, &callback)
|
69
|
+
|
70
|
+
TODO
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
|
74
|
+
```
|
75
|
+
|
76
|
+
Find the Product ID here:
|
77
|
+
|
78
|
+

|
79
|
+
|
80
|
+
|
81
|
+
|
82
|
+
## Contributing
|
83
|
+
|
84
|
+
1. Fork it
|
85
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
86
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
87
|
+
4. Make some specs pass
|
88
|
+
5. Push to the branch (`git iap origin my-new-feature`)
|
89
|
+
6. Create new Pull Request
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
unless defined?(Motion::Project::Config)
|
4
|
+
raise "ProMotion-iap must be required within a RubyMotion project."
|
5
|
+
end
|
6
|
+
|
7
|
+
Motion::Project::App.setup do |app|
|
8
|
+
lib_dir_path = File.dirname(File.expand_path(__FILE__))
|
9
|
+
app.files << File.join(lib_dir_path, "ProMotion/iap.rb")
|
10
|
+
app.frameworks << "StoreKit"
|
11
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
module ProMotion
|
2
|
+
module IAP
|
3
|
+
attr_accessor :completion_handlers
|
4
|
+
|
5
|
+
def purchase_iap(product_id, &callback)
|
6
|
+
iap_setup
|
7
|
+
retrieve_iaps product_id do |products|
|
8
|
+
products.each do |product|
|
9
|
+
self.completion_handlers["purchase-#{product[:product_id]}"] = callback
|
10
|
+
payment = SKPayment.paymentWithProduct(product[:product])
|
11
|
+
SKPaymentQueue.defaultQueue.addPayment(payment)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def restore_iaps(product_id, &callback)
|
17
|
+
iap_setup
|
18
|
+
retrieve_iaps product_id do |products|
|
19
|
+
products.each do |product|
|
20
|
+
self.completion_handlers["restore-#{product[:product_id]}"] = callback
|
21
|
+
SKPaymentQueue.defaultQueue.restoreCompletedTransactions
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def retrieve_iaps(*product_ids, &callback)
|
27
|
+
iap_setup
|
28
|
+
self.completion_handlers["retrieve_iaps"] = callback
|
29
|
+
@products_request = SKProductsRequest.alloc.initWithProductIdentifiers(NSSet.setWithArray(product_ids.flatten))
|
30
|
+
@products_request.delegate = self
|
31
|
+
@products_request.start
|
32
|
+
end
|
33
|
+
alias retrieve_iap retrieve_iaps
|
34
|
+
|
35
|
+
def completion_handlers
|
36
|
+
@completion_handlers ||= {}
|
37
|
+
end
|
38
|
+
|
39
|
+
# private methods
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def iap_setup
|
44
|
+
SKPaymentQueue.defaultQueue.addTransactionObserver(self)
|
45
|
+
end
|
46
|
+
|
47
|
+
def iap_shutdown
|
48
|
+
SKPaymentQueue.defaultQueue.removeTransactionObserver(self)
|
49
|
+
end
|
50
|
+
|
51
|
+
def retrieved_iaps_handler(products, &callback)
|
52
|
+
sk_products = products.map do |sk_product|
|
53
|
+
{
|
54
|
+
product_id: sk_product.productIdentifier,
|
55
|
+
title: sk_product.localizedTitle,
|
56
|
+
description: sk_product.localizedDescription,
|
57
|
+
formatted_price: formatted_iap_price(sk_product.price, sk_product.priceLocale),
|
58
|
+
price: sk_product.price,
|
59
|
+
price_locale: sk_product.priceLocale,
|
60
|
+
downloadable: sk_product.isDownloadable,
|
61
|
+
download_content_lengths: sk_product.downloadContentLengths,
|
62
|
+
download_content_version: sk_product.downloadContentVersion,
|
63
|
+
product: sk_product,
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
callback.call(sk_products, nil) if callback.arity == 2
|
68
|
+
callback.call(sk_products) if callback.arity < 2
|
69
|
+
end
|
70
|
+
|
71
|
+
def formatted_iap_price(price, price_locale)
|
72
|
+
num_formatter = NSNumberFormatter.new
|
73
|
+
num_formatter.setFormatterBehavior NSNumberFormatterBehaviorDefault
|
74
|
+
num_formatter.setNumberStyle NSNumberFormatterCurrencyStyle
|
75
|
+
num_formatter.setLocale price_locale
|
76
|
+
num_formatter.stringFromNumber price
|
77
|
+
end
|
78
|
+
|
79
|
+
public
|
80
|
+
|
81
|
+
# SKProductsRequestDelegate methods
|
82
|
+
|
83
|
+
def productsRequest(_, didReceiveResponse:response)
|
84
|
+
unless response.invalidProductIdentifiers.empty?
|
85
|
+
PM.logger.error "PM::IAP Error - invalid product identifier(s) '#{response.invalidProductIdentifiers.join("', '")}' for application identifier #{NSBundle.mainBundle.infoDictionary['CFBundleIdentifier'].inspect}"
|
86
|
+
end
|
87
|
+
retrieved_iaps_handler(response.products, &self.completion_handlers["retrieve_iaps"]) if self.completion_handlers["retrieve_iaps"]
|
88
|
+
@products_request = nil
|
89
|
+
self.completion_handlers["retrieve_iaps"] = nil
|
90
|
+
end
|
91
|
+
|
92
|
+
def request(_, didFailWithError:error)
|
93
|
+
self.completion_handlers["retrieve_iaps"].call([], error) if self.completion_handlers["retrieve_iaps"].arity == 2
|
94
|
+
self.completion_handlers["retrieve_iaps"].call([]) if self.completion_handlers["retrieve_iaps"].arity < 2
|
95
|
+
@products_request = nil
|
96
|
+
self.completion_handlers["retrieve_iaps"] = nil
|
97
|
+
end
|
98
|
+
|
99
|
+
# SKPaymentTransactionObserver methods
|
100
|
+
|
101
|
+
def paymentQueue(_, updatedTransactions:transactions)
|
102
|
+
transactions.each do |transaction|
|
103
|
+
case transaction.transactionState
|
104
|
+
when SKPaymentTransactionStatePurchasing then iap_callback(:in_progress, transaction)
|
105
|
+
when SKPaymentTransactionStateDeferred then iap_callback(:deferred, transaction)
|
106
|
+
when SKPaymentTransactionStatePurchased then iap_callback(:purchased, transaction, true)
|
107
|
+
when SKPaymentTransactionStateRestored then iap_callback(:restored, transaction, true)
|
108
|
+
when SKPaymentTransactionStateFailed
|
109
|
+
if transaction.error.code == SKErrorPaymentCancelled
|
110
|
+
iap_callback(:canceled, transaction, true)
|
111
|
+
else
|
112
|
+
iap_callback(:error, transaction, true)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def iap_callback(status, transaction, finish=false)
|
119
|
+
product_id = transaction.payment.productIdentifier
|
120
|
+
if self.completion_handlers["purchase-#{product_id}"]
|
121
|
+
self.completion_handlers["purchase-#{product_id}"].call status, transaction
|
122
|
+
self.completion_handlers["purchase-#{product_id}"] = nil if finish
|
123
|
+
end
|
124
|
+
if self.completion_handlers["restore-#{product_id}"]
|
125
|
+
self.completion_handlers["restore-#{product_id}"].call status, transaction
|
126
|
+
self.completion_handlers["restore-#{product_id}"] = nil if finish
|
127
|
+
end
|
128
|
+
SKPaymentQueue.defaultQueue.finishTransaction(transaction) if finish
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ProMotion-iap
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jamon Holmgren
|
8
|
+
- Kevin VanGelder
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-02-12 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ProMotion
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - "~>"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '2.0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - "~>"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '2.0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: motion-stump
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0.3'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0.3'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: motion-redgreen
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '1.0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '1.0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rake
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
description: Adds in-app purchase support to ProMotion.
|
71
|
+
email:
|
72
|
+
- jamon@clearsightstudio.com
|
73
|
+
- kevin@clearsightstudio.com
|
74
|
+
executables: []
|
75
|
+
extensions: []
|
76
|
+
extra_rdoc_files: []
|
77
|
+
files:
|
78
|
+
- README.md
|
79
|
+
- lib/ProMotion-iap.rb
|
80
|
+
- lib/ProMotion/iap.rb
|
81
|
+
homepage: https://github.com/clearsightstudio/ProMotion-iap
|
82
|
+
licenses:
|
83
|
+
- MIT
|
84
|
+
metadata: {}
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubyforge_project:
|
101
|
+
rubygems_version: 2.4.5
|
102
|
+
signing_key:
|
103
|
+
specification_version: 4
|
104
|
+
summary: Adds in-app purchase support to ProMotion.
|
105
|
+
test_files: []
|