(This is the duplicate of https://developer.apple.com/forums/thread/718948 because I accidentally marked it as completed.)
I am trying to test Ask to Buy for consumable product.
When the transaction was approved, the process stops at a breakpoint in Transaction.updates
. However, when I call Transaction.currentEntitlements
after that, I cannot handle transaction of consumables.
Here is my code.
func newTransactionListenerTask() -> Task<Void, Never> {
Task(priority: .background) {
for await verificationResult in Transaction.updates {
guard
case .verified(let transaction) = verificationResult,
transaction.revocationDate == nil
else { return }
// Breakpoint stops here
await refreshPurchasedProducts()
await transaction.finish()
}
}
}
func refreshPurchasedProducts() async {
for await verificationResult in Transaction.currentEntitlements {
guard case .verified(let transaction) = verificationResult else { return }
switch transaction.productType {
case .consumable:
// This code is not called
updateConsumablePurchaseCount(productID: transaction.productID)
default:
break
}
}
}
I do not call transaction.finish()
if the purchase result is .pending
as shown in the code below.
func purchase(_ info: ConsumableProductInfo) async throws {
let result: Product.PurchaseResult
switch info {
case .coffee:
guard let coffeeProduct else { return }
result = try await coffeeProduct.purchase()
}
switch result {
case let .success(verificationResult):
switch verificationResult {
case let .verified(transaction):
await refreshPurchasedProducts()
await transaction.finish()
case let .unverified(_, verificationError):
throw verificationError
}
case .pending, .userCancelled:
break
@unknown default:
break
}
}
When I test Ask to Buy I'm not calling transaction.finish()
so I should be able to get the consumable transaction in Transaction.currentEntitlements
, however I couldn't.
I found a blog post that is similar to this problem: https://iosexample.com/implementing-and-testing-in-app-purchases-with-storekit2-in-xcode-13-swift-5-5-and-ios-15/ It says that "In tests I've done transactions for consumables do not remain in the receipt, even if you omit to call finish()."
So I wonder if this is a bug or problem in my coding.
Transaction.currentEntitlements
never includes consumable in-app purchases, even if they are unfinished. The documentation says:
Consumable in-app purchases also don't appear in the current entitlements. To get transactions for unfinished consumables, use the
unfinished
orall
sequences inTransaction
.
For your specific use case, I would recommend checking Transaction.unfinished
since that will include all unfinished transactions, including transactions for consumable in-app purchases.