ProMotion-iap 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
![product id](http://clrsight.co/jh/2015-02-11-d8xw6.png?+)
|
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: []
|