0.3 C
New York
Sunday, February 23, 2025

ios – Utilizing StoreKit2 PurchaseManager


This is the code I exploit to buy merchandise utilizing StoreKit2. The place ought to I be calling listenForTransactions?

import StoreKit
import AmplitudeSwift

class PurchaseManager: ObservableObject {
    // A printed property to carry obtainable merchandise
    @Printed var merchandise: [Product] = []
    // A printed property to trace the standing of transactions
    @Printed var transactionState: String = "Idle"
    
    // A set of product identifiers
    non-public let productIdentifiers: Set = [
        PaymentHandler.sharedInstance.YEARLY_PRODUCT_ID,
        PaymentHandler.sharedInstance.YEARLY_PRODUCT_ID_50_OFF,
        PaymentHandler.sharedInstance.MONTHLY_PRODUCT_ID
    ]
    
    // Shared occasion for use all through the app
    static let shared = PurchaseManager()
    
    non-public init() {}
    
    // MARK: - Fetch Merchandise from App Retailer
    func fetchProducts() async {
        do {
            let merchandise = attempt await Product.merchandise(for: productIdentifiers)
            self.merchandise = merchandise
        } catch {
            print("Didn't fetch merchandise: (error.localizedDescription)")
        }
    }
    
    // MARK: - Deal with Buy
    func purchaseProduct(product: Product, supply: String) async -> Bool {
        do {
            // Begin the acquisition
            let consequence = attempt await product.buy()
            
            // Deal with the results of the acquisition
            swap consequence {
            case .success(let verificationResult):
                swap verificationResult {
                case .verified(let transaction):
                    self.transactionState = "Buy Profitable"
                    await transaction.end()
                    return true
                case .unverified(let transaction, let error):
                    self.transactionState = "Buy Unverified: (error.localizedDescription)"
                    await transaction.end()
                    await showMessageWithTitle("Error!", "There was an error processing your buy", .error)
                    return false
                }
            case .userCancelled:
                self.transactionState = "Consumer cancelled the acquisition."
               
                Amplitude.sharedInstance.monitor(
                    eventType: "payment_cancelled",
                    eventProperties: ["PlanId": product.id, "Source": source]
                )
                
            case .pending:
                self.transactionState = "Buy is pending."
                
                await showMessageWithTitle("Error!", "There was an error processing your buy", .error)
            @unknown default:
                self.transactionState = "Unknown buy consequence."
                
                await showMessageWithTitle("Error!", "There was an error processing your buy", .error)
                
                Amplitude.sharedInstance.monitor(
                    eventType: "payment_failed",
                    eventProperties: ["PlanId": product.id, "Source": source]
                )
                
            }
        } catch {
            self.transactionState = "Buy failed: (error.localizedDescription)"
            
            await showMessageWithTitle("Error!", "There was an error processing your buy", .error)
            
            Amplitude.sharedInstance.monitor(
                eventType: "payment_failed",
                eventProperties: ["PlanId": product.id, "Source": source]
            )
            
        }
        return false
    }
    
    // MARK: - Hear for Transaction Updates
    func listenForTransactionUpdates() {
        Activity {
            for await lead to Transaction.updates {
                swap consequence {
                case .verified(let transaction):
                    self.transactionState = "Transaction verified: (transaction.productID)"
                    await transaction.end()
                    // Unlock the content material related to the transaction
                case .unverified(let transaction, let error):
                    self.transactionState = "Unverified transaction: (error.localizedDescription)"
                    await transaction.end()
                }
            }
        }
    }
}

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles