ProMotion-iap 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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: []