-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added SKPayment and SKProductsRequest wrappers
- Loading branch information
Showing
4 changed files
with
94 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import StoreKit | ||
#if !COCOAPODS | ||
import PromiseKit | ||
#endif | ||
|
||
extension SKPayment { | ||
public func promise() -> Promise<SKPaymentTransaction> { | ||
return PaymentObserver(payment: self).promise | ||
} | ||
} | ||
|
||
fileprivate class PaymentObserver: NSObject, SKPaymentTransactionObserver { | ||
let (promise, fulfill, reject) = Promise<SKPaymentTransaction>.pending() | ||
let payment: SKPayment | ||
var retainCycle: PaymentObserver? | ||
|
||
init(payment: SKPayment) { | ||
self.payment = payment | ||
super.init() | ||
SKPaymentQueue.default().add(self) | ||
SKPaymentQueue.default().add(payment) | ||
retainCycle = self | ||
} | ||
|
||
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { | ||
guard let transaction = transactions.first(where: { $0.payment == payment }) else { | ||
return | ||
This comment has been minimized.
Sorry, something went wrong. |
||
} | ||
switch transaction.transactionState { | ||
case .purchased: | ||
queue.finishTransaction(transaction) | ||
fulfill(transaction) | ||
queue.remove(self) | ||
retainCycle = nil | ||
case .failed: | ||
let error = transaction.error ?? NSError.cancelledError() | ||
queue.finishTransaction(transaction) | ||
reject(error) | ||
queue.remove(self) | ||
retainCycle = nil | ||
default: | ||
break | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import StoreKit | ||
#if !COCOAPODS | ||
import PromiseKit | ||
#endif | ||
|
||
extension SKReceiptRefreshRequest { | ||
public func promise() -> Promise<SKReceiptRefreshRequest> { | ||
return ReceiptRefreshObserver(request: self).promise | ||
} | ||
} | ||
|
||
fileprivate class ReceiptRefreshObserver: NSObject, SKRequestDelegate { | ||
let (promise, fulfill, reject) = Promise<SKReceiptRefreshRequest>.pending() | ||
let request: SKReceiptRefreshRequest | ||
var retainCycle: ReceiptRefreshObserver? | ||
|
||
init(request: SKReceiptRefreshRequest) { | ||
self.request = request | ||
super.init() | ||
request.delegate = self | ||
request.start() | ||
retainCycle = self | ||
} | ||
|
||
|
||
func requestDidFinish(_ request: SKRequest) { | ||
fulfill(self.request) | ||
retainCycle = nil | ||
} | ||
|
||
func request(_ request: SKRequest, didFailWithError error: Error) { | ||
reject(error) | ||
retainCycle = nil | ||
} | ||
} |
@mpsnp @mxcl I've encountered an issue here where attempting a subscription purchase under the new StoreKit Testing in Xcode 12 has an updated transaction (
SKMutablePayment
) that is not equal to the storedSKPayment
(despite having all the same fields)In the case of a single transaction:
transactions.first!.payment == self.payment returns
true
initially if thetransactionState
of the payment in the queue is.purchasing
. However when thetransactionState
becomes.purchased
the equality check in the closure fails and the promise never resolves because theSKPayment
originally purchased is always skipped by theguard
statement when it shows up in theupdatedTransactions
listI've noticed that in the
.purchasing
state, the payment in the queue is anSKPayment
. However in the.purchased
state it is anSKMutablePayment
. I'm not sure if the guard statement here can be made robust to this, and I'm also not sure if this behaviour is unique to the StoreKit Testing feature of Xcode 12