react-native-iap 12.0.0 → 12.0.1
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.
- package/README.md +3 -1
- package/ios/IapTypes.swift +21 -0
- package/ios/RNIapIos.swift +8 -58
- package/ios/RNIapIosSk2.m +4 -0
- package/ios/RNIapIosSk2.swift +33 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,7 +28,9 @@ Please [fund the project](https://opencollective.com/react-native-iap) if you ar
|
|
|
28
28
|
|
|
29
29
|
## Announcement
|
|
30
30
|
|
|
31
|
-
- Version `
|
|
31
|
+
- Version `12.0.0`: Implements Amazon 3.x SDK including the new DRM verification.
|
|
32
|
+
|
|
33
|
+
- Version `11.0.0`: The module migrates OS sdk to [storekit2](https://developer.apple.com/videos/play/wwdc2021/10114). [andresesfm](https://github.com/andresesfm) is working hard on this.
|
|
32
34
|
|
|
33
35
|
```
|
|
34
36
|
yarn add react-native-iap@next
|
package/ios/IapTypes.swift
CHANGED
|
@@ -33,3 +33,24 @@ enum IapErrors: String, CaseIterable {
|
|
|
33
33
|
return IapErrors.allCases.firstIndex(of: self)!
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
+
|
|
37
|
+
// Based on https://stackoverflow.com/a/40135192/570612
|
|
38
|
+
extension Date {
|
|
39
|
+
var millisecondsSince1970: Int64 {
|
|
40
|
+
return Int64((self.timeIntervalSince1970 * 1000.0).rounded())
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
var millisecondsSince1970String: String {
|
|
44
|
+
return String((self.timeIntervalSince1970 * 1000.0).rounded())
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
init(milliseconds: Int64) {
|
|
48
|
+
self = Date(timeIntervalSince1970: TimeInterval(milliseconds) / 1000)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
extension SKProductsRequest {
|
|
53
|
+
var key: String {
|
|
54
|
+
return String(self.hashValue)
|
|
55
|
+
}
|
|
56
|
+
}
|
package/ios/RNIapIos.swift
CHANGED
|
@@ -1,27 +1,6 @@
|
|
|
1
1
|
import React
|
|
2
2
|
import StoreKit
|
|
3
3
|
|
|
4
|
-
// Based on https://stackoverflow.com/a/40135192/570612
|
|
5
|
-
extension Date {
|
|
6
|
-
var millisecondsSince1970: Int64 {
|
|
7
|
-
return Int64((self.timeIntervalSince1970 * 1000.0).rounded())
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
var millisecondsSince1970String: String {
|
|
11
|
-
return String((self.timeIntervalSince1970 * 1000.0).rounded())
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
init(milliseconds: Int64) {
|
|
15
|
-
self = Date(timeIntervalSince1970: TimeInterval(milliseconds) / 1000)
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
extension SKProductsRequest {
|
|
20
|
-
var key: String {
|
|
21
|
-
return String(self.hashValue)
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
4
|
@objc(RNIapIos)
|
|
26
5
|
class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver, SKProductsRequestDelegate {
|
|
27
6
|
private var promisesByKey: [String: [RNIapIosPromise]]
|
|
@@ -29,7 +8,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
29
8
|
private var hasListeners = false
|
|
30
9
|
private var pendingTransactionWithAutoFinish = false
|
|
31
10
|
private var receiptBlock: ((Data?, Error?) -> Void)? // Block to handle request the receipt async from delegate
|
|
32
|
-
private var validProducts: [SKProduct]
|
|
11
|
+
private var validProducts: [String: SKProduct]
|
|
33
12
|
private var promotedPayment: SKPayment?
|
|
34
13
|
private var promotedProduct: SKProduct?
|
|
35
14
|
private var productsRequest: SKProductsRequest?
|
|
@@ -40,7 +19,7 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
40
19
|
promisesByKey = [String: [RNIapIosPromise]]()
|
|
41
20
|
pendingTransactionWithAutoFinish = false
|
|
42
21
|
myQueue = DispatchQueue(label: "reject")
|
|
43
|
-
validProducts = [SKProduct]()
|
|
22
|
+
validProducts = [String: SKProduct]()
|
|
44
23
|
super.init()
|
|
45
24
|
addTransactionObserver()
|
|
46
25
|
}
|
|
@@ -212,16 +191,8 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
212
191
|
reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }
|
|
213
192
|
) {
|
|
214
193
|
pendingTransactionWithAutoFinish = andDangerouslyFinishTransactionAutomatically
|
|
215
|
-
var product: SKProduct?
|
|
216
|
-
|
|
217
|
-
lockQueue.sync {
|
|
218
|
-
for p in validProducts {
|
|
219
|
-
if sku == p.productIdentifier {
|
|
220
|
-
product = p
|
|
221
|
-
break
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
194
|
+
var product: SKProduct? = validProducts[sku]
|
|
195
|
+
|
|
225
196
|
if let prod = product {
|
|
226
197
|
addPromise(forKey: prod.productIdentifier, resolve: resolve, reject: reject)
|
|
227
198
|
|
|
@@ -391,12 +362,8 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
391
362
|
}
|
|
392
363
|
|
|
393
364
|
var items: [[String: Any?]] = [[:]]
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
lockQueue.sync {
|
|
397
|
-
for product in validProducts {
|
|
398
|
-
items.append(getProductObject(product))
|
|
399
|
-
}
|
|
365
|
+
for product in validProducts.values {
|
|
366
|
+
items.append(getProductObject(product))
|
|
400
367
|
}
|
|
401
368
|
|
|
402
369
|
resolvePromises(forKey: request.key, value: items)
|
|
@@ -405,25 +372,8 @@ class RNIapIos: RCTEventEmitter, SKRequestDelegate, SKPaymentTransactionObserver
|
|
|
405
372
|
// Add to valid products from Apple server response. Allowing getProducts, getSubscriptions call several times.
|
|
406
373
|
// Doesn't allow duplication. Replace new product.
|
|
407
374
|
func add(_ aProd: SKProduct) {
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
lockQueue.sync {
|
|
411
|
-
debugMessage("Add new object: \(aProd.productIdentifier)")
|
|
412
|
-
var delTar = -1
|
|
413
|
-
|
|
414
|
-
for k in 0..<validProducts.count {
|
|
415
|
-
let cur = validProducts[k]
|
|
416
|
-
if cur.productIdentifier == aProd.productIdentifier {
|
|
417
|
-
delTar = k
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
if delTar >= 0 {
|
|
422
|
-
validProducts.remove(at: delTar)
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
validProducts.append(aProd)
|
|
426
|
-
}
|
|
375
|
+
debugMessage("Add new object: \(aProd.productIdentifier)")
|
|
376
|
+
validProducts[aProd.productIdentifier] = aProd
|
|
427
377
|
}
|
|
428
378
|
|
|
429
379
|
func request(_ request: SKRequest, didFailWithError error: Error) {
|
package/ios/RNIapIosSk2.m
CHANGED
|
@@ -85,5 +85,9 @@ RCT_EXTERN_METHOD(presentCodeRedemptionSheet:
|
|
|
85
85
|
(RCTPromiseResolveBlock)resolve
|
|
86
86
|
reject:(RCTPromiseRejectBlock)reject)
|
|
87
87
|
|
|
88
|
+
RCT_EXTERN_METHOD(clearTransaction:
|
|
89
|
+
(RCTPromiseResolveBlock)resolve
|
|
90
|
+
reject:(RCTPromiseRejectBlock)reject)
|
|
91
|
+
|
|
88
92
|
@end
|
|
89
93
|
#endif
|
package/ios/RNIapIosSk2.swift
CHANGED
|
@@ -85,6 +85,11 @@ protocol Sk2Delegate {
|
|
|
85
85
|
reject: @escaping RCTPromiseRejectBlock
|
|
86
86
|
)
|
|
87
87
|
|
|
88
|
+
func clearTransaction(
|
|
89
|
+
_ resolve: @escaping RCTPromiseResolveBlock,
|
|
90
|
+
reject: @escaping RCTPromiseRejectBlock
|
|
91
|
+
)
|
|
92
|
+
|
|
88
93
|
func startObserving()
|
|
89
94
|
func stopObserving()
|
|
90
95
|
}
|
|
@@ -203,6 +208,10 @@ class DummySk2: Sk2Delegate {
|
|
|
203
208
|
reject(errorCode, errorMessage, nil)
|
|
204
209
|
}
|
|
205
210
|
|
|
211
|
+
func clearTransaction(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
212
|
+
reject(errorCode, errorMessage, nil)
|
|
213
|
+
}
|
|
214
|
+
|
|
206
215
|
func startObserving() {
|
|
207
216
|
}
|
|
208
217
|
|
|
@@ -361,6 +370,12 @@ class RNIapIosSk2: RCTEventEmitter, Sk2Delegate {
|
|
|
361
370
|
) {
|
|
362
371
|
delegate.presentCodeRedemptionSheet(resolve, reject: reject)
|
|
363
372
|
}
|
|
373
|
+
|
|
374
|
+
@objc func clearTransaction(
|
|
375
|
+
_ resolve: @escaping RCTPromiseResolveBlock = { _ in },
|
|
376
|
+
reject: @escaping RCTPromiseRejectBlock = { _, _, _ in }) {
|
|
377
|
+
delegate.clearTransaction(resolve, reject: reject)
|
|
378
|
+
}
|
|
364
379
|
}
|
|
365
380
|
|
|
366
381
|
@available(iOS 15.0, tvOS 15.0, *)
|
|
@@ -810,4 +825,22 @@ class RNIapIosSk2iOS15: Sk2Delegate {
|
|
|
810
825
|
reject(IapErrors.E_USER_CANCELLED.rawValue, "This method is not available on tvOS", nil)
|
|
811
826
|
#endif
|
|
812
827
|
}
|
|
828
|
+
|
|
829
|
+
func clearTransaction(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
|
|
830
|
+
Task {
|
|
831
|
+
for await result in Transaction.unfinished {
|
|
832
|
+
do {
|
|
833
|
+
// Check whether the transaction is verified. If it isn’t, catch `failedVerification` error.
|
|
834
|
+
let transaction = try checkVerified(result)
|
|
835
|
+
debugMessage("Finishing transaction")
|
|
836
|
+
await transaction.finish()
|
|
837
|
+
debugMessage("Finished transaction")
|
|
838
|
+
transactions.removeValue(forKey: String(transaction.id))
|
|
839
|
+
} catch {
|
|
840
|
+
debugMessage("Failed to finish transaction")
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
resolve(nil)
|
|
844
|
+
}
|
|
845
|
+
}
|
|
813
846
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-iap",
|
|
3
|
-
"version": "12.0.
|
|
3
|
+
"version": "12.0.1",
|
|
4
4
|
"description": "React Native In App Purchase Module.",
|
|
5
5
|
"repository": "https://github.com/dooboolab/react-native-iap",
|
|
6
6
|
"author": "dooboolab <support@dooboolab.com> (https://github.com/dooboolab)",
|