Question

Given an SKPaymentTransaction is there a way to get the SKProduct?

I'm trying to implement a generic SKPaymentTransactionObserver that will allow my app to be notified of all in-app purchases that occur. I have implemented the SKPaymentTransactionObserver interface, and I am getting the paymentQueue: updatedTransactions: callback firing correctly. In my callback I have access to the SKPaymentTransaction object, and from there I can get the SKPayment object. From the payment I cannot find a way to get the SKProduct though.

This is frustrating since the SKPayment must have been created using the SKProduct, but the interface only allows the user to get the productIdentifier. To create an SKPayment

Really, I want to get access to the cost, quantity, and local currency that was spent, and these are properties of the SKProduct.

The only way I can see to do this is to swizzle [SKPayment paymentWithProduct:]` and intercept payment creation, which is an awful prospect.

Was it helpful?

Solution

I don't think it is possible right now to get that information from the the SKPaymentTransaction or its SKPayment object.

You could query this information though by setting up a SKProductRequest with one or more product identifiers. The response is handled by productsRequest:didReceiveResponse.

Apple's documentation has a pretty good example of how to do it here.

OTHER TIPS

Given an SKPaymentTransaction is there a way to get the SKProduct?

You could get the productIdentifier from the transaction object from which you can get the product info if you have an array of SKProducts by looking up the array for productIdentifier,

transaction.payment.productIdentifier

I ran into this problem, too. (I wanted to get the product's price upon successful purchase.) My solution is to store the each SKProduct in a Dictionary, using the productIdentifier as the key. Here's the gist of my implementation (in Swift 3):

Declare the dictionary as a property in your class:

fileprivate var products = Dictionary<String, SKProduct>()

Store products in the dictionary when the productsRequest(_:didReceive:) callback function of SKProductsRequestDelegate is called:

extension PurchaseManager: SKProductsRequestDelegate {
    func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        for product in response.products {
            products[product.productIdentifier] = product
        }
    }
}

When the paymentQueue(_:updatedTransactions:) callback function of SKPaymentTransactionObserver is called, retrieve the product from the dictionary:

func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
    for transaction in transactions {
        let product = products[transaction.payment.productIdentifier]
        let price = product?.price
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top